blob: 06110ca13a6293d5e8b5a51e118fdde93d9ab51c [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070022#include "Interface.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070024#include "Reference.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070025#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070026#include "Scope.h"
27
Andreas Huberdca261f2016-08-04 13:47:51 -070028#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070029#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000030#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070032#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070033#include <vector>
34
35namespace android {
36
Andreas Huber737080b2016-08-02 15:38:04 -070037void AST::getPackageComponents(
38 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070039 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070040}
41
42void AST::getPackageAndVersionComponents(
43 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070044 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070045}
46
Steven Moreland5708edf2016-11-04 15:33:31 +000047std::string AST::makeHeaderGuard(const std::string &baseName,
48 bool indicateGenerated) const {
49 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070050
Steven Moreland5708edf2016-11-04 15:33:31 +000051 if (indicateGenerated) {
52 guard += "HIDL_GENERATED_";
53 }
54
55 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070056 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000057 guard += StringHelper::Uppercase(baseName);
58 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070059
60 return guard;
61}
62
Steven Morelandee88eed2016-10-31 17:49:00 -070063void AST::generateCppPackageInclude(
64 Formatter &out,
65 const FQName &package,
66 const std::string &klass) {
67
68 out << "#include <";
69
70 std::vector<std::string> components;
71 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
72
73 for (const auto &component : components) {
74 out << component << "/";
75 }
76
77 out << klass
78 << ".h>\n";
79}
80
Andreas Huber881227d2016-08-02 14:20:21 -070081void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
82 std::vector<std::string> packageComponents;
83 getPackageAndVersionComponents(
84 &packageComponents, true /* cpp_compatible */);
85
86 if (enter) {
87 for (const auto &component : packageComponents) {
88 out << "namespace " << component << " {\n";
89 }
Andreas Huber0e00de42016-08-03 09:56:02 -070090
Andreas Huber2831d512016-08-15 09:33:47 -070091 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -070092 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -070093 out.setNamespace(std::string());
94
Andreas Huber881227d2016-08-02 14:20:21 -070095 for (auto it = packageComponents.rbegin();
96 it != packageComponents.rend();
97 ++it) {
98 out << "} // namespace " << *it << "\n";
99 }
100 }
101}
102
Steven Moreland038903b2017-03-30 12:11:24 -0700103static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
104 const std::string functionName = isTry ? "tryGetService" : "getService";
105
Steven Moreland7645fbd2019-03-12 18:49:28 -0700106 if (isTry) {
107 DocComment(
108 "This gets the service of this type with the specified instance name. If the\n"
109 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
110 "device, this will return nullptr. This is useful when you don't want to block\n"
111 "during device boot. If getStub is true, this will try to return an unwrapped\n"
112 "passthrough implementation in the same process. This is useful when getting an\n"
113 "implementation from the same partition/compilation group.\n\n"
114 "In general, prefer getService(std::string,bool)")
115 .emit(out);
116 } else {
117 DocComment(
118 "This gets the service of this type with the specified instance name. If the\n"
119 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
120 "nullptr. If the service is not available, this will wait for the service to\n"
121 "become available. If the service is a lazy service, this will start the service\n"
122 "and return when it becomes available. If getStub is true, this will try to\n"
123 "return an unwrapped passthrough implementation in the same process. This is\n"
124 "useful when getting an implementation from the same partition/compilation group.")
125 .emit(out);
126 }
Steven Moreland038903b2017-03-30 12:11:24 -0700127 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800128 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700129 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700130 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800131 << "const char serviceName[], bool getStub=false)"
132 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700133 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700134 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700135 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700139 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700140 DocComment("Calls " + functionName +
141 "(\"default\", bool). This is the recommended instance name for singleton services.")
142 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
144 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
145}
146
147static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
148 declareGetService(out, interfaceName, true /* isTry */);
149 declareGetService(out, interfaceName, false /* isTry */);
150
Steven Moreland7645fbd2019-03-12 18:49:28 -0700151 DocComment(
152 "Registers a service with the service manager. For Trebilized devices, the service\n"
153 "must also be in the VINTF manifest.")
154 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700155 out << "__attribute__ ((warn_unused_result))"
156 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700157 DocComment("Registers for notifications for when a service is registered.").emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "&notification);\n";
163 });
164
165}
166
Steven Moreland038903b2017-03-30 12:11:24 -0700167static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800170
171 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700172 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700174 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000175 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800176 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700177 out << "return ::android::hardware::details::getServiceInternal<"
178 << fqName.getInterfaceProxyName()
179 << ">(serviceName, "
180 << (!isTry ? "true" : "false") // retry
181 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800182 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700183}
184
185static void implementServiceManagerInteractions(Formatter &out,
186 const FQName &fqName, const std::string &package) {
187
188 const std::string interfaceName = fqName.getInterfaceName();
189
190 implementGetService(out, fqName, true /* isTry */);
191 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800192
Yifan Hongeefe4f22017-01-04 15:32:42 -0800193 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800194 << "const std::string &serviceName) ";
195 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700196 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800197 }).endl().endl();
198
Yifan Hongeefe4f22017-01-04 15:32:42 -0800199 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800200 out.indent(2, [&] {
201 out << "const std::string &serviceName,\n"
202 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
203 << "&notification) ";
204 });
205 out.block([&] {
206 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
207 out.indent(2, [&] {
208 out << "= ::android::hardware::defaultServiceManager();\n";
209 });
210 out.sIf("sm == nullptr", [&] {
211 out << "return false;\n";
212 }).endl();
213 out << "::android::hardware::Return<bool> success =\n";
214 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800215 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800216 out.indent(2, [&] {
217 out << "serviceName, notification);\n";
218 });
219 });
220 out << "return success.isOk() && success;\n";
221 }).endl().endl();
222}
223
Steven Moreland368e4602018-02-16 14:21:49 -0800224void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700225 const Interface *iface = getInterface();
226 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700227 const std::string guard = makeHeaderGuard(ifaceName);
228
229 out << "#ifndef " << guard << "\n";
230 out << "#define " << guard << "\n\n";
231
Andreas Huber737080b2016-08-02 15:38:04 -0700232 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700233 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700234 }
235
236 if (!mImportedNames.empty()) {
237 out << "\n";
238 }
239
Steven Moreland19f11b52017-05-12 18:22:21 -0700240 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800241 if (isIBase()) {
242 out << "// skipped #include IServiceNotification.h\n\n";
243 } else {
244 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
245 }
Steven Moreland0693f312016-11-09 15:06:14 -0800246 }
247
Yifan Hongc8934042016-11-17 17:10:52 -0800248 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700249 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700250
Steven Moreland19f11b52017-05-12 18:22:21 -0700251 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200252 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700253 }
254
Martijn Coenenaf712c02016-11-16 15:26:27 +0100255 out << "#include <utils/NativeHandle.h>\n";
256 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700257
258 enterLeaveNamespace(out, true /* enter */);
259 out << "\n";
260
Steven Moreland19f11b52017-05-12 18:22:21 -0700261 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700262 iface->emitDocComment(out);
263
Andreas Huber881227d2016-08-02 14:20:21 -0700264 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700265 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700266
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700267 const Interface *superType = iface->superType();
268
Yi Kong56758da2018-07-24 16:21:37 -0700269 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700271 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000272 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700273 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700274 }
275
276 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700277
278 out.indent();
279
Steven Moreland7645fbd2019-03-12 18:49:28 -0700280 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.")
281 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700282 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700283
Steven Moreland7645fbd2019-03-12 18:49:28 -0700284 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"")
285 .emit(out);
286 out << "static const char* descriptor;\n\n";
287
Steven Moreland70cb55e2019-03-12 17:20:54 -0700288 iface->emitTypeDeclarations(out);
289 } else {
290 mRootScope.emitTypeDeclarations(out);
291 }
Andreas Huber881227d2016-08-02 14:20:21 -0700292
Steven Moreland19f11b52017-05-12 18:22:21 -0700293 if (iface) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700294 DocComment(
295 "Returns whether this object's implementation is outside of the current process.")
296 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800297 out << "virtual bool isRemote() const ";
298 if (!isIBase()) {
299 out << "override ";
300 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700301 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800302
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700303 for (const auto& tuple : iface->allMethodsFromRoot()) {
304 const Method* method = tuple.method();
305
Andreas Huber881227d2016-08-02 14:20:21 -0700306 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700307
Andreas Huber881227d2016-08-02 14:20:21 -0700308 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700309 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800310
311 if (elidedReturn == nullptr && returnsValue) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700312 DocComment("Return callback for " + method->name()).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800313 out << "using "
314 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700315 << "_cb = std::function<void(";
316 method->emitCppResultSignature(out, true /* specify namespaces */);
317 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800318 }
Andreas Huber881227d2016-08-02 14:20:21 -0700319
Andreas Huber3599d922016-08-09 10:42:57 -0700320 method->dumpAnnotations(out);
321
Steven Moreland49bad8d2018-05-17 15:45:26 -0700322 method->emitDocComment(out);
323
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700324 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700325 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700326 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700327 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700328 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700329 }
330
331 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700332 << "(";
333 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700334 out << ")";
335 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800336 if (!isIBase()) {
337 out << " override";
338 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700339 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700340 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700341 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700342 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700343 }
Steven Moreland40786312016-08-16 10:29:40 -0700344
Steven Moreland7645fbd2019-03-12 18:49:28 -0700345 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800346 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700347
Yifan Hong3d746092016-12-07 14:26:33 -0800348 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700349 DocComment(
350 "This performs a checked cast based on what the underlying implementation "
351 "actually is.")
352 .emit(out);
Yifan Hong200209c2017-03-29 03:39:09 -0700353 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800354 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700355 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800356 << superType->getCppArgumentType()
357 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700358 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700359 }
360
Yifan Hongc8934042016-11-17 17:10:52 -0800361 if (isIBase()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700362 out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800363 } else {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700364 out << "\n// helper methods for interactions with the hwservicemanager\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800365 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800366 }
Andreas Huber881227d2016-08-02 14:20:21 -0700367 }
368
Steven Moreland19f11b52017-05-12 18:22:21 -0700369 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700370 out.unindent();
371
Andreas Hubere3f769a2016-10-10 10:54:44 -0700372 out << "};\n\n";
373 }
374
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700375 out << "//\n";
376 out << "// type declarations for package\n";
377 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800378 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700379 out << "//\n";
380 out << "// type header definitions for package\n";
381 out << "//\n\n";
382 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700383
384 out << "\n";
385 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700386 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700387
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700388 out << "//\n";
389 out << "// global type declarations for package\n";
390 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800391 mRootScope.emitGlobalTypeDeclarations(out);
392
Andreas Huber881227d2016-08-02 14:20:21 -0700393 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700394}
395
Steven Moreland368e4602018-02-16 14:21:49 -0800396void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700397 const Interface *iface = getInterface();
398 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700399
Steven Moreland40786312016-08-16 10:29:40 -0700400 const std::string guard = makeHeaderGuard(klassName);
401
402 out << "#ifndef " << guard << "\n";
403 out << "#define " << guard << "\n\n";
404
Steven Moreland19f11b52017-05-12 18:22:21 -0700405 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700406
Steven Morelandee88eed2016-10-31 17:49:00 -0700407 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700408
409 for (const auto &item : mImportedNames) {
410 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800411 generateCppPackageInclude(out, item, "hwtypes");
412 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800413 generateCppPackageInclude(out, item, item.getInterfaceStubName());
414 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700415 }
Steven Moreland40786312016-08-16 10:29:40 -0700416 }
417
418 out << "\n";
419
Martijn Coenen93915102016-09-01 01:35:52 +0200420 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700421 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100422 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700423
424 out << "\n";
425
426 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700427
Steven Moreland368e4602018-02-16 14:21:49 -0800428 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700429
430 enterLeaveNamespace(out, false /* enter */);
431
432 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700433}
434
Steven Moreland58a20c72018-10-09 12:30:51 -0700435static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
436 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800437 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700438 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800439 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700440 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800441 const Interface &iface = static_cast<const Interface &>(arg->type());
442 out << iface.getCppStackType() << " " << wrappedName << ";\n";
443 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
444 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
445 out << wrappedName
446 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700447 << "::android::hardware::details::wrapPassthrough("
448 << name
449 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800450 out.sIf(wrappedName + " == nullptr", [&] {
451 // Fatal error. Happens when the BsFoo class is not found in the binary
452 // or any dynamic libraries.
453 handleError();
454 }).endl();
455 }).sElse([&] {
456 out << wrappedName << " = " << name << ";\n";
457 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700458
459 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800460}
461
Steven Moreland616cf4d2018-10-02 13:52:18 -0700462void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700463 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700464
Steven Moreland58a20c72018-10-09 12:30:51 -0700465 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700466 out.indent();
467
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800468 if (method->isHidlReserved()
469 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
470 method->cppImpl(IMPL_PASSTHROUGH, out);
471 out.unindent();
472 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800473 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800474 }
475
Steven Moreland69e7c702016-09-09 11:16:32 -0700476 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700477 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700478
Steven Moreland67f67b42016-09-29 08:59:02 -0700479 if (returnsValue && elidedReturn == nullptr) {
480 generateCheckNonNull(out, "_hidl_cb");
481 }
482
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700483 generateCppInstrumentationCall(
484 out,
485 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700486 method,
487 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700488
Steven Moreland58a20c72018-10-09 12:30:51 -0700489 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800490 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700491 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800492 out << "return ::android::hardware::Status::fromExceptionCode(\n";
493 out.indent(2, [&] {
494 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800495 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800496 });
497 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700498
499 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800500 }
501
Steven Moreland58a20c72018-10-09 12:30:51 -0700502 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700503 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700504
505 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700506 out << "addOnewayTask([mImpl = this->mImpl\n"
507 << "#ifdef __ANDROID_DEBUGGABLE__\n"
508 ", mEnableInstrumentation = this->mEnableInstrumentation, "
509 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
510 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700511 for (const std::string& arg : wrappedArgNames) {
512 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700513 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700514 out << "] {\n";
515 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700516 }
517
518 out << "mImpl->"
519 << method->name()
520 << "(";
521
Yifan Hong932464e2017-03-30 15:40:22 -0700522 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800523 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700524 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700525
526 std::function<void(void)> kHandlePassthroughError = [&] {
527 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
528 out.indent(2, [&] {
529 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
530 << "\"Cannot wrap passthrough interface.\");\n";
531 });
532 };
533
Steven Moreland69e7c702016-09-09 11:16:32 -0700534 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700535 // never true if oneway since oneway methods don't return values
536
Steven Moreland69e7c702016-09-09 11:16:32 -0700537 if (!method->args().empty()) {
538 out << ", ";
539 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800540 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700541 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800542 out << "const auto &_hidl_out_"
543 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700544 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800545
546 out << ") {\n";
547 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700548 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800549 out,
550 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700551 method,
552 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800553
Steven Moreland58a20c72018-10-09 12:30:51 -0700554 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800555 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700556 wrappedOutNames.push_back(
557 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800558 }
559
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800560 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700561 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
562 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800563 out << ");\n";
564 out.unindent();
565 out << "});\n\n";
566 } else {
567 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700568
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800569 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700570 const std::string outName = "_hidl_out_" + elidedReturn->name();
571
572 out << elidedReturn->type().getCppResultType() << " " << outName
573 << " = _hidl_return;\n";
574 out << "(void) " << outName << ";\n";
575
576 const std::string wrappedName =
577 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
578
579 if (outName != wrappedName) {
580 // update the original value since it is used by generateCppInstrumentationCall
581 out << outName << " = " << wrappedName << ";\n\n";
582
583 // update the value to be returned
584 out << "_hidl_return = " << outName << "\n;";
585 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800586 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700587 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800588 out,
589 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700590 method,
591 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700592 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700593
594 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700595 out.unindent();
596 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700597 } else {
598 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700599 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700600
601 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700602
603 out.unindent();
604 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700605}
606
Steven Moreland368e4602018-02-16 14:21:49 -0800607void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700608 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700609
Yifan Hong10fe0b52016-10-19 14:20:17 -0700610 const Interface *prevIterface = nullptr;
611 for (const auto &tuple : iface->allMethodsFromRoot()) {
612 const Method *method = tuple.method();
613 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700614
Steven Morelandf16c5c02017-07-31 16:50:06 -0700615 if (!includeParent && superInterface != iface) {
616 continue;
617 }
618
Yifan Hong10fe0b52016-10-19 14:20:17 -0700619 if(prevIterface != superInterface) {
620 if (prevIterface != nullptr) {
621 out << "\n";
622 }
623 out << "// Methods from "
624 << superInterface->fullName()
625 << " follow.\n";
626 prevIterface = superInterface;
627 }
Steven Moreland368e4602018-02-16 14:21:49 -0800628 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700629 }
630
Yifan Hong10fe0b52016-10-19 14:20:17 -0700631 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700632}
633
Steven Moreland0b843772017-06-23 16:33:38 -0700634void AST::generateTemplatizationLink(Formatter& out) const {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700635 DocComment("The pure class is what this class wraps.").emit(out);
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700636 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700637}
638
Steven Moreland1a52e822017-07-27 13:56:29 -0700639void AST::generateCppTag(Formatter& out, const std::string& tag) const {
640 out << "typedef " << tag << " _hidl_tag;\n\n";
641}
642
Steven Moreland368e4602018-02-16 14:21:49 -0800643void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800644 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700645
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700646 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800647 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700648 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700649
650 out << "#ifndef " << guard << "\n";
651 out << "#define " << guard << "\n\n";
652
Yifan Hongeefe4f22017-01-04 15:32:42 -0800653 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700654
Steven Morelandee88eed2016-10-31 17:49:00 -0700655 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700656
657 enterLeaveNamespace(out, true /* enter */);
658 out << "\n";
659
660 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800661 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100662 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800663 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000664 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100665 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800666 out << " : public "
667 << gIBaseFqName.getInterfaceStubFqName().cppName()
668 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100669 }
Andreas Huber881227d2016-08-02 14:20:21 -0700670
671 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800672 out << "explicit "
673 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700674 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100675 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800676 out << "explicit "
677 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700678 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800679 << " const std::string& HidlInstrumentor_package,"
680 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700681 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000682 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700683 out << "::android::status_t onTransact(\n";
684 out.indent();
685 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700686 out << "uint32_t _hidl_code,\n";
687 out << "const ::android::hardware::Parcel &_hidl_data,\n";
688 out << "::android::hardware::Parcel *_hidl_reply,\n";
689 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700690 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700691 out.unindent();
692 out.unindent();
693
Steven Moreland0b843772017-06-23 16:33:38 -0700694 out.endl();
695 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700696 DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
697 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700698 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700699
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800700 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700701
Steven Moreland368e4602018-02-16 14:21:49 -0800702 generateMethods(out,
703 [&](const Method* method, const Interface*) {
704 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
705 return;
706 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700707
Steven Moreland368e4602018-02-16 14:21:49 -0800708 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700709
Steven Moreland368e4602018-02-16 14:21:49 -0800710 out.indent(2,
711 [&] {
712 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
713 << "const ::android::hardware::Parcel &_hidl_data,\n"
714 << "::android::hardware::Parcel *_hidl_reply,\n"
715 << "TransactCallback _hidl_cb);\n";
716 })
717 .endl()
718 .endl();
719 },
720 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700721
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100722 out.unindent();
723 out << "private:\n";
724 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800725
Steven Moreland368e4602018-02-16 14:21:49 -0800726 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800727 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800728 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800729 }
730 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700731 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800732
733 if (elidedReturn == nullptr && returnsValue) {
734 out << "using " << method->name() << "_cb = "
735 << iface->fqName().cppName()
736 << "::" << method->name() << "_cb;\n";
737 }
738 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800739 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800740 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800741
Steven Moreland19f11b52017-05-12 18:22:21 -0700742 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700743 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700744 out << "};\n\n";
745
746 enterLeaveNamespace(out, false /* enter */);
747
748 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700749}
750
Steven Moreland368e4602018-02-16 14:21:49 -0800751void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700752 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700753 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800754 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700755 }
756
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700757 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800758 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800759 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700760
761 out << "#ifndef " << guard << "\n";
762 out << "#define " << guard << "\n\n";
763
Martijn Coenen115d4282016-12-19 05:14:04 +0100764 out << "#include <hidl/HidlTransportSupport.h>\n\n";
765
Andreas Huber881227d2016-08-02 14:20:21 -0700766 std::vector<std::string> packageComponents;
767 getPackageAndVersionComponents(
768 &packageComponents, false /* cpp_compatible */);
769
Yifan Hongeefe4f22017-01-04 15:32:42 -0800770 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700771 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700772
773 enterLeaveNamespace(out, true /* enter */);
774 out << "\n";
775
776 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800777 << proxyName
778 << " : public ::android::hardware::BpInterface<"
779 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000780 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700781
782 out.indent();
783
Yifan Hongeefe4f22017-01-04 15:32:42 -0800784 out << "explicit "
785 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700786 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700787 << "\n\n";
788
Steven Moreland0b843772017-06-23 16:33:38 -0700789 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700790 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
791 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700792 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700793
Yifan Hong10fe0b52016-10-19 14:20:17 -0700794 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700795
Steven Moreland368e4602018-02-16 14:21:49 -0800796 generateMethods(
797 out,
798 [&](const Method* method, const Interface*) {
799 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
800 return;
801 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700802
Steven Moreland368e4602018-02-16 14:21:49 -0800803 out << "static ";
804 method->generateCppReturnType(out);
805 out << " _hidl_" << method->name() << "("
806 << "::android::hardware::IInterface* _hidl_this, "
807 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700808
Steven Moreland368e4602018-02-16 14:21:49 -0800809 if (!method->hasEmptyCppArgSignature()) {
810 out << ", ";
811 }
812 method->emitCppArgSignature(out);
813 out << ");\n";
814 },
815 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700816
Steven Moreland368e4602018-02-16 14:21:49 -0800817 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700818 method->generateCppSignature(out);
819 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700820 });
Steven Moreland9c387612016-09-07 09:54:26 -0700821
Andreas Huber881227d2016-08-02 14:20:21 -0700822 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100823 out << "private:\n";
824 out.indent();
825 out << "std::mutex _hidl_mMutex;\n"
826 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
827 << " _hidl_mDeathRecipients;\n";
828 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700829 out << "};\n\n";
830
831 enterLeaveNamespace(out, false /* enter */);
832
833 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700834}
835
Steven Moreland368e4602018-02-16 14:21:49 -0800836void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700837 std::string baseName = getBaseName();
838 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700839
Steven Morelanda885d252017-09-25 18:44:43 -0700840 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700841
Steven Moreland623c0042017-01-13 14:42:29 -0800842 out << "#define LOG_TAG \""
843 << mPackage.string() << "::" << baseName
844 << "\"\n\n";
845
Steven Moreland5add34d2018-11-08 16:31:30 -0800846 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100847 out << "#include <cutils/trace.h>\n";
848 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700849 out << "#include <hidl/Static.h>\n";
850 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700851 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700852 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700853 // This is a no-op for IServiceManager itself.
854 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
855
Yifan Hongeefe4f22017-01-04 15:32:42 -0800856 generateCppPackageInclude(out, mPackage, iface->getProxyName());
857 generateCppPackageInclude(out, mPackage, iface->getStubName());
858 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700859
860 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700861 generateCppPackageInclude(out,
862 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800863 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700864 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800865
866 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700867 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700868 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800869 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700870 }
871
872 out << "\n";
873
874 enterLeaveNamespace(out, true /* enter */);
875 out << "\n";
876
Steven Moreland368e4602018-02-16 14:21:49 -0800877 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700878
Steven Moreland368e4602018-02-16 14:21:49 -0800879 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700880 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700881
882 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800883 out << "const char* "
884 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700885 << "::descriptor(\""
886 << iface->fqName().string()
887 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800888 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100889 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800890 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800891 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800892 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800893 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800894 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800895 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800896 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800897 out << "return new "
898 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700899 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800900 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800901 << " *>(iIntf));\n";
902 });
Yifan Hongb04de382017-02-06 15:31:52 -0800903 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800904 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800905 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800906 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800907 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800908 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800909 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800910 << gIBaseFqName.cppName()
911 << "> {\n";
912 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800913 out << "return new "
914 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700915 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800916 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800917 << " *>(iIntf));\n";
918 });
Yifan Hongb04de382017-02-06 15:31:52 -0800919 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800920 });
Yifan Hong158655a2016-11-08 12:34:07 -0800921 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100922 out << "};\n\n";
923 out << "__attribute__((destructor))";
924 out << "static void static_destructor() {\n";
925 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800926 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100927 << iface->localName()
928 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800929 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100930 << iface->localName()
931 << "::descriptor);\n";
932 });
933 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800934
Steven Moreland368e4602018-02-16 14:21:49 -0800935 generateInterfaceSource(out);
936 generateProxySource(out, iface->fqName());
937 generateStubSource(out, iface);
938 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700939
Yifan Hongc8934042016-11-17 17:10:52 -0800940 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800941 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800942 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800943 std::string package = iface->fqName().package()
944 + iface->fqName().atVersion();
945
Yifan Hongeefe4f22017-01-04 15:32:42 -0800946 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800947 }
Steven Moreland40786312016-08-16 10:29:40 -0700948 }
949
Andreas Huber6755e9d2017-04-06 11:09:07 -0700950 HidlTypeAssertion::EmitAll(out);
951 out << "\n";
952
Andreas Huber881227d2016-08-02 14:20:21 -0700953 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700954}
955
Steven Moreland67f67b42016-09-29 08:59:02 -0700956void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -0800957 out.sIf(nonNull + " == nullptr", [&] {
958 out << "return ::android::hardware::Status::fromExceptionCode(\n";
959 out.indent(2, [&] {
Steven Moreland610002f2017-06-16 13:02:49 -0700960 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
961 << "\"Null synchronous callback passed.\");\n";
Yifan Honga018ed52016-12-13 16:35:08 -0800962 });
963 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -0700964}
965
Steven Moreland368e4602018-02-16 14:21:49 -0800966void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
967 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700968}
969
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700970void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
971 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700972 if (args.empty()) {
973 return;
974 }
975
976 for (const auto &arg : args) {
977 const Type &type = arg->type();
978
Yifan Hong3b320f82016-11-01 15:15:54 -0700979 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700980 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700981 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700982 << ";\n";
983 }
984
985 out << "\n";
986}
987
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700988void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
989 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
990 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700991 const Type &type = arg->type();
992
Andreas Huber881227d2016-08-02 14:20:21 -0700993 type.emitReaderWriter(
994 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700995 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700996 parcelObj,
997 parcelObjIsPointer,
998 isReader,
999 mode);
1000}
1001
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001002void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
1003 bool parcelObjIsPointer, const NamedReference<Type>* arg,
1004 bool isReader, Type::ErrorMode mode,
1005 bool addPrefixToName) const {
Yifan Hongbf459bc2016-08-23 16:50:37 -07001006 const Type &type = arg->type();
1007 if(type.needsResolveReferences()) {
1008 type.emitResolveReferences(
1009 out,
1010 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1011 isReader, // nameIsPointer
1012 parcelObj,
1013 parcelObjIsPointer,
1014 isReader,
1015 mode);
1016 }
1017}
1018
Steven Moreland368e4602018-02-16 14:21:49 -08001019void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
1020 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -07001021 method->generateCppSignature(out,
1022 klassName,
1023 true /* specify namespaces */);
1024
Martijn Coenen115d4282016-12-19 05:14:04 +01001025 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001026 out.block([&] {
1027 method->cppImpl(IMPL_PROXY, out);
1028 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -08001029 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001030 }
1031
Steven Morelandf16c5c02017-07-31 16:50:06 -07001032 out.block([&] {
1033 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001034 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001035
1036 method->generateCppReturnType(out);
1037
1038 out << " _hidl_out = "
1039 << superInterface->fqName().cppNamespace()
1040 << "::"
1041 << superInterface->getProxyName()
1042 << "::_hidl_"
1043 << method->name()
1044 << "(this, this";
1045
1046 if (!method->hasEmptyCppArgSignature()) {
1047 out << ", ";
1048 }
1049
1050 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1051 out << arg->name();
1052 });
1053
1054 if (returnsValue && elidedReturn == nullptr) {
1055 if (!method->args().empty()) {
1056 out << ", ";
1057 }
1058 out << "_hidl_cb";
1059 }
1060
1061 out << ");\n\n";
1062
1063 out << "return _hidl_out;\n";
1064 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001065}
1066
Steven Moreland368e4602018-02-16 14:21:49 -08001067void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001068 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001069 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001070 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001071 }
1072
1073 method->generateCppReturnType(out);
1074
1075 out << klassName
1076 << "::_hidl_"
1077 << method->name()
1078 << "("
1079 << "::android::hardware::IInterface *_hidl_this, "
1080 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1081
1082 if (!method->hasEmptyCppArgSignature()) {
1083 out << ", ";
1084 }
1085
1086 method->emitCppArgSignature(out);
1087 out << ") {\n";
1088
1089 out.indent();
1090
1091 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1092 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1093 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1094 out << "#else\n";
1095 out << "(void) _hidl_this_instrumentor;\n";
1096 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1097
1098 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001099 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hong068c5522016-10-31 14:07:25 -07001100 if (returnsValue && elidedReturn == nullptr) {
1101 generateCheckNonNull(out, "_hidl_cb");
1102 }
1103
Steven Moreland92a08a72017-07-31 14:57:37 -07001104 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001105 out,
1106 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001107 method,
1108 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001109
1110 out << "::android::hardware::Parcel _hidl_data;\n";
1111 out << "::android::hardware::Parcel _hidl_reply;\n";
1112 out << "::android::status_t _hidl_err;\n";
1113 out << "::android::hardware::Status _hidl_status;\n\n";
1114
1115 declareCppReaderLocals(
1116 out, method->results(), true /* forResults */);
1117
1118 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001119 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001120 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001121 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1122
Martijn Coenenfff73352017-01-04 16:36:31 +01001123 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001124 // First DFS: write all buffers and resolve pointers for parent
1125 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001126 if (arg->type().isInterface()) {
1127 hasInterfaceArgument = true;
1128 }
Yifan Hong068c5522016-10-31 14:07:25 -07001129 emitCppReaderWriter(
1130 out,
1131 "_hidl_data",
1132 false /* parcelObjIsPointer */,
1133 arg,
1134 false /* reader */,
1135 Type::ErrorMode_Goto,
1136 false /* addPrefixToName */);
1137 }
1138
1139 // Second DFS: resolve references.
1140 for (const auto &arg : method->args()) {
1141 emitCppResolveReferences(
1142 out,
1143 "_hidl_data",
1144 false /* parcelObjIsPointer */,
1145 arg,
1146 false /* reader */,
1147 Type::ErrorMode_Goto,
1148 false /* addPrefixToName */);
1149 }
1150
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001151 if (hasInterfaceArgument) {
1152 // Start binder threadpool to handle incoming transactions
1153 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1154 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001155 out << "_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001156 << method->getSerialId()
1157 << " /* "
1158 << method->name()
1159 << " */, _hidl_data, &_hidl_reply";
1160
1161 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001162 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Yifan Hong068c5522016-10-31 14:07:25 -07001163 }
1164 out << ");\n";
1165
1166 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1167
1168 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001169 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001170 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1171 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1172
1173
1174 // First DFS: write all buffers and resolve pointers for parent
1175 for (const auto &arg : method->results()) {
1176 emitCppReaderWriter(
1177 out,
1178 "_hidl_reply",
1179 false /* parcelObjIsPointer */,
1180 arg,
1181 true /* reader */,
1182 Type::ErrorMode_Goto,
1183 true /* addPrefixToName */);
1184 }
1185
1186 // Second DFS: resolve references.
1187 for (const auto &arg : method->results()) {
1188 emitCppResolveReferences(
1189 out,
1190 "_hidl_reply",
1191 false /* parcelObjIsPointer */,
1192 arg,
1193 true /* reader */,
1194 Type::ErrorMode_Goto,
1195 true /* addPrefixToName */);
1196 }
1197
1198 if (returnsValue && elidedReturn == nullptr) {
1199 out << "_hidl_cb(";
1200
Yifan Hong932464e2017-03-30 15:40:22 -07001201 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001202 if (arg->type().resultNeedsDeref()) {
1203 out << "*";
1204 }
1205 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001206 });
Yifan Hong068c5522016-10-31 14:07:25 -07001207
1208 out << ");\n\n";
1209 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001210 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001211
Steven Moreland92a08a72017-07-31 14:57:37 -07001212 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001213 out,
1214 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001215 method,
1216 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001217
1218 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001219 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1220 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001221 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001222 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1223 } else {
1224 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1225 out << "return ::android::hardware::Return<void>();\n\n";
1226 }
1227
1228 out.unindent();
1229 out << "_hidl_error:\n";
1230 out.indent();
1231 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1232 out << "return ::android::hardware::Return<";
1233 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001234 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001235 } else {
1236 out << "void";
1237 }
1238 out << ">(_hidl_status);\n";
1239
1240 out.unindent();
1241 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001242}
1243
Steven Moreland368e4602018-02-16 14:21:49 -08001244void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001245 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001246
1247 out << klassName
1248 << "::"
1249 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001250 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001251
1252 out.indent();
1253 out.indent();
1254
1255 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001256 << "<"
1257 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001258 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001259 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001260 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001261 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001262 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001263 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001264
Andreas Huber881227d2016-08-02 14:20:21 -07001265 out.unindent();
1266 out.unindent();
1267 out << "}\n\n";
1268
Steven Moreland368e4602018-02-16 14:21:49 -08001269 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001270 [&](const Method* method, const Interface* superInterface) {
1271 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001272 },
1273 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001274
Steven Moreland368e4602018-02-16 14:21:49 -08001275 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1276 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001277 });
Andreas Huber881227d2016-08-02 14:20:21 -07001278}
1279
Steven Moreland368e4602018-02-16 14:21:49 -08001280void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001281 const std::string interfaceName = iface->localName();
1282 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001283
Steven Moreland40786312016-08-16 10:29:40 -07001284 out << klassName
1285 << "::"
1286 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001287 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001288
1289 out.indent();
1290 out.indent();
1291
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001292 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001293 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001294 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001295 out << ": "
1296 << gIBaseFqName.getInterfaceStubFqName().cppName()
1297 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001298 }
1299
1300 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001301 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001302 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001303 << "\") { \n";
1304 out.indent();
1305 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001306 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001307 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1308 out << "mSchedPolicy = prio.sched_policy;\n";
1309 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001310 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1311 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001312 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001313
1314 out.unindent();
1315 out.unindent();
1316 out << "}\n\n";
1317
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001318 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001319 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001320 // class properly.
1321 out << klassName
1322 << "::"
1323 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001324 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1325 << " const std::string &HidlInstrumentor_package,"
1326 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001327
1328 out.indent();
1329 out.indent();
1330
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001331 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001332 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001333 out.indent();
1334 out << "_hidl_mImpl = _hidl_impl;\n";
1335 out.unindent();
1336
1337 out.unindent();
1338 out.unindent();
1339 out << "}\n\n";
1340 }
1341
Steven Moreland57a89362017-07-21 19:29:54 +00001342 out << klassName << "::~" << klassName << "() ";
1343 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001344 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1345 })
1346 .endl()
1347 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001348
Steven Moreland368e4602018-02-16 14:21:49 -08001349 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001350 [&](const Method* method, const Interface* superInterface) {
1351 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001352 },
1353 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001354
Steven Moreland368e4602018-02-16 14:21:49 -08001355 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001356 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001357 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001358 }
1359 method->generateCppSignature(out, iface->getStubName());
1360 out << " ";
1361 out.block([&] {
1362 method->cppImpl(IMPL_STUB_IMPL, out);
1363 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001364 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001365
Andreas Huber881227d2016-08-02 14:20:21 -07001366 out << "::android::status_t " << klassName << "::onTransact(\n";
1367
1368 out.indent();
1369 out.indent();
1370
Iliyan Malchev549e2592016-08-10 08:59:12 -07001371 out << "uint32_t _hidl_code,\n"
1372 << "const ::android::hardware::Parcel &_hidl_data,\n"
1373 << "::android::hardware::Parcel *_hidl_reply,\n"
1374 << "uint32_t _hidl_flags,\n"
1375 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001376
1377 out.unindent();
1378
Iliyan Malchev549e2592016-08-10 08:59:12 -07001379 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001380 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001381 out.indent();
1382
Yifan Hong10fe0b52016-10-19 14:20:17 -07001383 for (const auto &tuple : iface->allMethodsFromRoot()) {
1384 const Method *method = tuple.method();
1385 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001386
Howard Chen71f289f2017-08-29 17:35:01 +08001387 if (!isIBase() && method->isHidlReserved()) {
1388 continue;
1389 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001390 out << "case "
1391 << method->getSerialId()
1392 << " /* "
1393 << method->name()
1394 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001395
Yifan Hong10fe0b52016-10-19 14:20:17 -07001396 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001397
Steven Moreland77943692018-08-09 12:53:42 -07001398 out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
1399 << ";\n";
Steven Morelandebd8c722017-11-03 14:47:32 -07001400 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
1401 out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
1402
Steven Moreland368e4602018-02-16 14:21:49 -08001403 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001404
1405 out.unindent();
1406 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001407 }
1408
1409 out << "default:\n{\n";
1410 out.indent();
1411
Martijn Coenen225bc922017-06-27 14:39:46 -07001412 if (iface->isIBase()) {
1413 out << "(void)_hidl_flags;\n";
1414 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1415 } else {
1416 out << "return ";
1417 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1418 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001419
Martijn Coenen225bc922017-06-27 14:39:46 -07001420 out.indent();
1421 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001422
Martijn Coenen225bc922017-06-27 14:39:46 -07001423 out << "_hidl_code, _hidl_data, _hidl_reply, "
1424 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001425
Martijn Coenen225bc922017-06-27 14:39:46 -07001426 out.unindent();
1427 out.unindent();
1428 }
Andreas Huber881227d2016-08-02 14:20:21 -07001429
1430 out.unindent();
1431 out << "}\n";
1432
1433 out.unindent();
1434 out << "}\n\n";
1435
Yifan Honga018ed52016-12-13 16:35:08 -08001436 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1437 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1438 out.indent(2, [&] {
1439 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1440 out << "_hidl_reply);\n";
1441 });
1442 });
Andreas Huber881227d2016-08-02 14:20:21 -07001443
Iliyan Malchev549e2592016-08-10 08:59:12 -07001444 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001445
1446 out.unindent();
1447 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001448}
1449
Steven Moreland368e4602018-02-16 14:21:49 -08001450void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1451 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001452 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1453 method->cppImpl(IMPL_STUB, out);
1454 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001455 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001456 }
1457
Steven Morelandf16c5c02017-07-31 16:50:06 -07001458 out << "_hidl_err = "
1459 << superInterface->fqName().cppNamespace()
1460 << "::"
1461 << superInterface->getStubName()
1462 << "::_hidl_"
1463 << method->name()
1464 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1465 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001466}
1467
Steven Moreland368e4602018-02-16 14:21:49 -08001468void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001469 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001470 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001471 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001472 }
1473
Steven Morelandf8197902018-01-30 15:38:37 -08001474 const std::string& klassName = fqName.getInterfaceStubName();
1475
Steven Morelandf16c5c02017-07-31 16:50:06 -07001476 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1477
1478 out.indent();
1479 out.indent();
1480
1481 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1482 << "const ::android::hardware::Parcel &_hidl_data,\n"
1483 << "::android::hardware::Parcel *_hidl_reply,\n"
1484 << "TransactCallback _hidl_cb) {\n";
1485
1486 out.unindent();
1487
1488 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1489 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1490 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1491 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1492
1493 out << "::android::status_t _hidl_err = ::android::OK;\n";
1494
Yifan Hongeefe4f22017-01-04 15:32:42 -08001495 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001496 << klassName
1497 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001498
Andreas Huber881227d2016-08-02 14:20:21 -07001499 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001500 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001501 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001502 out.unindent();
1503 out << "}\n\n";
1504
Andreas Huber5e44a292016-09-27 14:52:39 -07001505 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001506
Yifan Hongbf459bc2016-08-23 16:50:37 -07001507 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001508 for (const auto &arg : method->args()) {
1509 emitCppReaderWriter(
1510 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001511 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001512 false /* parcelObjIsPointer */,
1513 arg,
1514 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001515 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001516 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001517 }
1518
Yifan Hongbf459bc2016-08-23 16:50:37 -07001519 // Second DFS: resolve references
1520 for (const auto &arg : method->args()) {
1521 emitCppResolveReferences(
1522 out,
1523 "_hidl_data",
1524 false /* parcelObjIsPointer */,
1525 arg,
1526 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001527 Type::ErrorMode_Return,
Yifan Hongbf459bc2016-08-23 16:50:37 -07001528 false /* addPrefixToName */);
1529 }
1530
Steven Moreland92a08a72017-07-31 14:57:37 -07001531 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001532 out,
1533 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001534 method,
1535 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001536
Andreas Huber881227d2016-08-02 14:20:21 -07001537 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001538 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001539
1540 std::string callee;
1541
1542 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1543 callee = "_hidl_this";
1544 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001545 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001546 }
Andreas Huber881227d2016-08-02 14:20:21 -07001547
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001548 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001549 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001550 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001551 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001552 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001553 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001554 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001555
Yifan Hong932464e2017-03-30 15:40:22 -07001556 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001557 if (arg->type().resultNeedsDeref()) {
1558 out << "*";
1559 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001560 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001561 });
Andreas Huber881227d2016-08-02 14:20:21 -07001562
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001563 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001564
Yifan Hong859e53f2016-11-14 19:08:24 -08001565 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1566 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001567
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001568 elidedReturn->type().emitReaderWriter(
1569 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001570 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001571 "_hidl_reply",
1572 true, /* parcelObjIsPointer */
1573 false, /* isReader */
1574 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001575
Yifan Hongbf459bc2016-08-23 16:50:37 -07001576 emitCppResolveReferences(
1577 out,
1578 "_hidl_reply",
1579 true /* parcelObjIsPointer */,
1580 elidedReturn,
1581 false /* reader */,
1582 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001583 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001584
Steven Moreland92a08a72017-07-31 14:57:37 -07001585 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001586 out,
1587 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001588 method,
1589 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001590
Iliyan Malchev549e2592016-08-10 08:59:12 -07001591 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001592 } else {
1593 if (returnsValue) {
1594 out << "bool _hidl_callbackCalled = false;\n\n";
1595 }
Andreas Huber881227d2016-08-02 14:20:21 -07001596
Steven Moreland30232dc2019-03-05 19:39:10 -08001597 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1598 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001599
Yifan Hong932464e2017-03-30 15:40:22 -07001600 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001601 if (arg->type().resultNeedsDeref()) {
1602 out << "*";
1603 }
1604
1605 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001606 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001607
1608 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001609 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001610 out << ", ";
1611 }
1612
1613 out << "[&](";
1614
Yifan Hong932464e2017-03-30 15:40:22 -07001615 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001616 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001617 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001618
1619 out << ") {\n";
1620 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001621 out << "if (_hidl_callbackCalled) {\n";
1622 out.indent();
1623 out << "LOG_ALWAYS_FATAL(\""
1624 << method->name()
1625 << ": _hidl_cb called a second time, but must be called once.\");\n";
1626 out.unindent();
1627 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 out << "_hidl_callbackCalled = true;\n\n";
1629
Yifan Hong859e53f2016-11-14 19:08:24 -08001630 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1631 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001632
Yifan Hongbf459bc2016-08-23 16:50:37 -07001633 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001634 for (const auto &arg : method->results()) {
1635 emitCppReaderWriter(
1636 out,
1637 "_hidl_reply",
1638 true /* parcelObjIsPointer */,
1639 arg,
1640 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001641 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001642 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001643 }
1644
Yifan Hongbf459bc2016-08-23 16:50:37 -07001645 // Second DFS: resolve references
1646 for (const auto &arg : method->results()) {
1647 emitCppResolveReferences(
1648 out,
1649 "_hidl_reply",
1650 true /* parcelObjIsPointer */,
1651 arg,
1652 false /* reader */,
1653 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001654 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001655 }
1656
Steven Moreland92a08a72017-07-31 14:57:37 -07001657 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001658 out,
1659 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001660 method,
1661 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001662
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001663 out << "_hidl_cb(*_hidl_reply);\n";
1664
1665 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001666 out << "});\n\n";
1667 } else {
1668 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001669 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001670 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001671 out,
1672 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001673 method,
1674 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001675 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001676
Steven Moreland30232dc2019-03-05 19:39:10 -08001677 out << "_hidl_ret.assertOk();\n";
1678
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001679 if (returnsValue) {
1680 out << "if (!_hidl_callbackCalled) {\n";
1681 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001682 out << "LOG_ALWAYS_FATAL(\""
1683 << method->name()
1684 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001685 out.unindent();
1686 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001687 } else {
1688 out << "::android::hardware::writeToParcel("
1689 << "::android::hardware::Status::ok(), "
1690 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001691 }
Andreas Huber881227d2016-08-02 14:20:21 -07001692 }
1693
Steven Morelandf16c5c02017-07-31 16:50:06 -07001694 out << "return _hidl_err;\n";
1695 out.unindent();
1696 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001697}
1698
Steven Moreland368e4602018-02-16 14:21:49 -08001699void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001700 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001701 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001702 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001703 }
1704
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001705 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001706 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001707
Yifan Hongeefe4f22017-01-04 15:32:42 -08001708 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001709
1710 bool supportOneway = iface->hasOnewayMethods();
1711
Steven Moreland69e7c702016-09-09 11:16:32 -07001712 const std::string guard = makeHeaderGuard(klassName);
1713
1714 out << "#ifndef " << guard << "\n";
1715 out << "#define " << guard << "\n\n";
1716
1717 std::vector<std::string> packageComponents;
1718 getPackageAndVersionComponents(
1719 &packageComponents, false /* cpp_compatible */);
1720
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001721 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001722 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001723 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001724
Steven Moreland19f11b52017-05-12 18:22:21 -07001725 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001726 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001727
Yifan Hong7a118f52016-12-07 11:21:15 -08001728 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001729 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001730 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001731 }
1732
1733 enterLeaveNamespace(out, true /* enter */);
1734 out << "\n";
1735
1736 out << "struct "
1737 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001738 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001739 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001740
1741 out.indent();
1742 out << "explicit "
1743 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001744 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001745 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001746 << "> impl);\n";
1747
Steven Moreland0b843772017-06-23 16:33:38 -07001748 out.endl();
1749 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001750 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001751
Steven Moreland616cf4d2018-10-02 13:52:18 -07001752 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1753 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001754 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001755
Steven Moreland69e7c702016-09-09 11:16:32 -07001756 out.unindent();
1757 out << "private:\n";
1758 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001759 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001760
1761 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001762 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001763
1764 out << "\n";
1765
1766 out << "::android::hardware::Return<void> addOnewayTask("
1767 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001768 }
1769
1770 out.unindent();
1771
1772 out << "};\n\n";
1773
1774 enterLeaveNamespace(out, false /* enter */);
1775
1776 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001777}
1778
Steven Moreland368e4602018-02-16 14:21:49 -08001779void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001780 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001781
Yifan Hong2d7126b2016-10-20 15:12:57 -07001782 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001783 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001784
Steven Moreland368e4602018-02-16 14:21:49 -08001785 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001786 bool reserved = method->isHidlReserved();
1787
1788 if (!reserved) {
1789 out << "// no default implementation for: ";
1790 }
1791 method->generateCppSignature(out, iface->localName());
1792 if (reserved) {
1793 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001794 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001795 }).endl();
1796 }
1797
1798 out << "\n";
1799
Steven Moreland368e4602018-02-16 14:21:49 -08001800 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001801 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001802
Yifan Hong3d746092016-12-07 14:26:33 -08001803 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001804 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001805 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001806 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001807 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001808 << "::castFrom("
1809 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001810 << " parent, bool "
1811 << (iface == superType ? "/* emitError */" : "emitError")
1812 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001813 out.indent();
1814 if (iface == superType) {
1815 out << "return parent;\n";
1816 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001817 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001818 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001819 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001820 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001821 << ">(\n";
1822 out.indent();
1823 out.indent();
1824 out << "parent, \""
1825 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001826 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001827 out.unindent();
1828 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001829 }
Yifan Hong3d746092016-12-07 14:26:33 -08001830 out.unindent();
1831 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001832 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001833}
1834
Steven Moreland368e4602018-02-16 14:21:49 -08001835void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001836 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001837
Yifan Hongeefe4f22017-01-04 15:32:42 -08001838 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001839
1840 out << klassName
1841 << "::"
1842 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001843 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001844 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001845 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001846 << mPackage.string()
1847 << "\", \""
1848 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001849 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001850 if (iface->hasOnewayMethods()) {
1851 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001852 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001853 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001854 });
1855 }
1856 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001857
1858 if (iface->hasOnewayMethods()) {
1859 out << "::android::hardware::Return<void> "
1860 << klassName
1861 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1862 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001863 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001864 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001865 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1866 out.indent();
1867 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07001868 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1869 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07001870 out.unindent();
1871 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001872 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001873 out << "}\n";
1874
Steven Morelandd366c262016-10-11 15:29:10 -07001875 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001876
1877 out.unindent();
1878 out << "}\n\n";
1879
1880
1881 }
Steven Moreland69e7c702016-09-09 11:16:32 -07001882}
1883
Steven Moreland92a08a72017-07-31 14:57:37 -07001884void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001885 InstrumentationEvent event,
1886 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001887 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001888 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001889 switch (event) {
1890 case SERVER_API_ENTRY:
1891 {
1892 out << "atrace_begin(ATRACE_TAG_HAL, \""
1893 << baseString + "::server\");\n";
1894 break;
1895 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001896 case PASSTHROUGH_ENTRY:
1897 {
1898 out << "atrace_begin(ATRACE_TAG_HAL, \""
1899 << baseString + "::passthrough\");\n";
1900 break;
1901 }
1902 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001903 case PASSTHROUGH_EXIT:
1904 {
1905 out << "atrace_end(ATRACE_TAG_HAL);\n";
1906 break;
1907 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001908 // client uses scope because of gotos
1909 // this isn't done for server because the profiled code isn't alone in its scope
1910 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1911 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001912 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1913 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001914 break;
1915 }
1916 case CLIENT_API_EXIT:
1917 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001918 default:
1919 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001920 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001921 }
1922 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001923}
1924
Steven Moreland92a08a72017-07-31 14:57:37 -07001925void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001926 Formatter &out,
1927 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001928 const Method *method,
1929 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001930 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001931
Steven Moreland30b76e92017-06-02 18:52:24 -07001932 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001933 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1934 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001935 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001936 std::string event_str = "";
1937 switch (event) {
1938 case SERVER_API_ENTRY:
1939 {
1940 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1941 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001942 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001943 << (arg->type().resultNeedsDeref() ? "" : "&")
1944 << arg->name()
1945 << ");\n";
1946 }
1947 break;
1948 }
1949 case SERVER_API_EXIT:
1950 {
1951 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001952 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001953 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001954 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001955 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001956 }
1957 break;
1958 }
1959 case CLIENT_API_ENTRY:
1960 {
1961 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1962 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001963 out << "_hidl_args.push_back((void *)&"
1964 << arg->name()
1965 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001966 }
1967 break;
1968 }
1969 case CLIENT_API_EXIT:
1970 {
1971 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1972 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001973 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001974 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001975 << "_hidl_out_"
1976 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001977 << ");\n";
1978 }
1979 break;
1980 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001981 case PASSTHROUGH_ENTRY:
1982 {
1983 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1984 for (const auto &arg : method->args()) {
1985 out << "_hidl_args.push_back((void *)&"
1986 << arg->name()
1987 << ");\n";
1988 }
1989 break;
1990 }
1991 case PASSTHROUGH_EXIT:
1992 {
1993 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001994 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001995 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001996 << arg->name()
1997 << ");\n";
1998 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001999 break;
2000 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002001 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002002 {
Steven Morelandcbff5612017-10-11 17:01:54 -07002003 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002004 }
2005 }
2006
Steven Moreland1ab31442016-11-03 18:37:51 -07002007 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002008 out.indent();
2009 out << "callback("
2010 << event_str
2011 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002012 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002013 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002014 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002015 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002016 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002017 << "\", \""
2018 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002019 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002020 out.unindent();
2021 out << "}\n";
2022 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07002023 out << "}\n";
2024 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002025}
2026
Andreas Huber881227d2016-08-02 14:20:21 -07002027} // namespace android