blob: cf8381ee8437239590b68ea3ebb2733dcb6ec21e [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070022#include "Interface.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070024#include "Reference.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070025#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070026#include "Scope.h"
27
Andreas Huberdca261f2016-08-04 13:47:51 -070028#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070029#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000030#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070032#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070033#include <vector>
34
35namespace android {
36
Andreas Huber737080b2016-08-02 15:38:04 -070037void AST::getPackageComponents(
38 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070039 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070040}
41
42void AST::getPackageAndVersionComponents(
43 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070044 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070045}
46
Steven Moreland5708edf2016-11-04 15:33:31 +000047std::string AST::makeHeaderGuard(const std::string &baseName,
48 bool indicateGenerated) const {
49 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070050
Steven Moreland5708edf2016-11-04 15:33:31 +000051 if (indicateGenerated) {
52 guard += "HIDL_GENERATED_";
53 }
54
55 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070056 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000057 guard += StringHelper::Uppercase(baseName);
58 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070059
60 return guard;
61}
62
Steven Morelandee88eed2016-10-31 17:49:00 -070063void AST::generateCppPackageInclude(
64 Formatter &out,
65 const FQName &package,
66 const std::string &klass) {
67
68 out << "#include <";
69
70 std::vector<std::string> components;
71 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
72
73 for (const auto &component : components) {
74 out << component << "/";
75 }
76
77 out << klass
78 << ".h>\n";
79}
80
Andreas Huber881227d2016-08-02 14:20:21 -070081void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
82 std::vector<std::string> packageComponents;
83 getPackageAndVersionComponents(
84 &packageComponents, true /* cpp_compatible */);
85
86 if (enter) {
87 for (const auto &component : packageComponents) {
88 out << "namespace " << component << " {\n";
89 }
Andreas Huber0e00de42016-08-03 09:56:02 -070090
Andreas Huber2831d512016-08-15 09:33:47 -070091 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -070092 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -070093 out.setNamespace(std::string());
94
Andreas Huber881227d2016-08-02 14:20:21 -070095 for (auto it = packageComponents.rbegin();
96 it != packageComponents.rend();
97 ++it) {
98 out << "} // namespace " << *it << "\n";
99 }
100 }
101}
102
Steven Moreland038903b2017-03-30 12:11:24 -0700103static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
104 const std::string functionName = isTry ? "tryGetService" : "getService";
105
Steven Moreland7645fbd2019-03-12 18:49:28 -0700106 if (isTry) {
107 DocComment(
108 "This gets the service of this type with the specified instance name. If the\n"
109 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
110 "device, this will return nullptr. This is useful when you don't want to block\n"
111 "during device boot. If getStub is true, this will try to return an unwrapped\n"
112 "passthrough implementation in the same process. This is useful when getting an\n"
113 "implementation from the same partition/compilation group.\n\n"
114 "In general, prefer getService(std::string,bool)")
115 .emit(out);
116 } else {
117 DocComment(
118 "This gets the service of this type with the specified instance name. If the\n"
119 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
120 "nullptr. If the service is not available, this will wait for the service to\n"
121 "become available. If the service is a lazy service, this will start the service\n"
122 "and return when it becomes available. If getStub is true, this will try to\n"
123 "return an unwrapped passthrough implementation in the same process. This is\n"
124 "useful when getting an implementation from the same partition/compilation group.")
125 .emit(out);
126 }
Steven Moreland038903b2017-03-30 12:11:24 -0700127 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800128 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700129 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700130 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800131 << "const char serviceName[], bool getStub=false)"
132 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700133 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700134 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700135 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700139 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700140 DocComment("Calls " + functionName +
141 "(\"default\", bool). This is the recommended instance name for singleton services.")
142 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
144 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
145}
146
147static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
148 declareGetService(out, interfaceName, true /* isTry */);
149 declareGetService(out, interfaceName, false /* isTry */);
150
Steven Moreland7645fbd2019-03-12 18:49:28 -0700151 DocComment(
152 "Registers a service with the service manager. For Trebilized devices, the service\n"
153 "must also be in the VINTF manifest.")
154 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700155 out << "__attribute__ ((warn_unused_result))"
156 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700157 DocComment("Registers for notifications for when a service is registered.").emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "&notification);\n";
163 });
164
165}
166
Steven Moreland038903b2017-03-30 12:11:24 -0700167static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800170
171 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700172 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700174 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000175 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800176 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700177 out << "return ::android::hardware::details::getServiceInternal<"
178 << fqName.getInterfaceProxyName()
179 << ">(serviceName, "
180 << (!isTry ? "true" : "false") // retry
181 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800182 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700183}
184
185static void implementServiceManagerInteractions(Formatter &out,
186 const FQName &fqName, const std::string &package) {
187
188 const std::string interfaceName = fqName.getInterfaceName();
189
190 implementGetService(out, fqName, true /* isTry */);
191 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800192
Yifan Hongeefe4f22017-01-04 15:32:42 -0800193 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800194 << "const std::string &serviceName) ";
195 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700196 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800197 }).endl().endl();
198
Yifan Hongeefe4f22017-01-04 15:32:42 -0800199 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800200 out.indent(2, [&] {
201 out << "const std::string &serviceName,\n"
202 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
203 << "&notification) ";
204 });
205 out.block([&] {
206 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
207 out.indent(2, [&] {
208 out << "= ::android::hardware::defaultServiceManager();\n";
209 });
210 out.sIf("sm == nullptr", [&] {
211 out << "return false;\n";
212 }).endl();
213 out << "::android::hardware::Return<bool> success =\n";
214 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800215 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800216 out.indent(2, [&] {
217 out << "serviceName, notification);\n";
218 });
219 });
220 out << "return success.isOk() && success;\n";
221 }).endl().endl();
222}
223
Steven Moreland368e4602018-02-16 14:21:49 -0800224void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700225 const Interface *iface = getInterface();
226 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700227 const std::string guard = makeHeaderGuard(ifaceName);
228
229 out << "#ifndef " << guard << "\n";
230 out << "#define " << guard << "\n\n";
231
Andreas Huber737080b2016-08-02 15:38:04 -0700232 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700233 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700234 }
235
236 if (!mImportedNames.empty()) {
237 out << "\n";
238 }
239
Steven Moreland19f11b52017-05-12 18:22:21 -0700240 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800241 if (isIBase()) {
242 out << "// skipped #include IServiceNotification.h\n\n";
243 } else {
244 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
245 }
Steven Moreland0693f312016-11-09 15:06:14 -0800246 }
247
Yifan Hongc8934042016-11-17 17:10:52 -0800248 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700249 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700250
Steven Moreland19f11b52017-05-12 18:22:21 -0700251 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200252 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700253 }
254
Martijn Coenenaf712c02016-11-16 15:26:27 +0100255 out << "#include <utils/NativeHandle.h>\n";
256 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700257
258 enterLeaveNamespace(out, true /* enter */);
259 out << "\n";
260
Steven Moreland19f11b52017-05-12 18:22:21 -0700261 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700262 iface->emitDocComment(out);
263
Andreas Huber881227d2016-08-02 14:20:21 -0700264 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700265 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700266
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700267 const Interface *superType = iface->superType();
268
Yi Kong56758da2018-07-24 16:21:37 -0700269 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700271 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000272 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700273 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700274 }
275
276 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700277
278 out.indent();
279
Steven Moreland7645fbd2019-03-12 18:49:28 -0700280 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.")
281 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700282 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700283
Steven Moreland7645fbd2019-03-12 18:49:28 -0700284 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"")
285 .emit(out);
286 out << "static const char* descriptor;\n\n";
287
Steven Moreland70cb55e2019-03-12 17:20:54 -0700288 iface->emitTypeDeclarations(out);
289 } else {
290 mRootScope.emitTypeDeclarations(out);
291 }
Andreas Huber881227d2016-08-02 14:20:21 -0700292
Steven Moreland19f11b52017-05-12 18:22:21 -0700293 if (iface) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700294 DocComment(
295 "Returns whether this object's implementation is outside of the current process.")
296 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800297 out << "virtual bool isRemote() const ";
298 if (!isIBase()) {
299 out << "override ";
300 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700301 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800302
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700303 for (const auto& tuple : iface->allMethodsFromRoot()) {
304 const Method* method = tuple.method();
305
Andreas Huber881227d2016-08-02 14:20:21 -0700306 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700307
Andreas Huber881227d2016-08-02 14:20:21 -0700308 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700309 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800310
311 if (elidedReturn == nullptr && returnsValue) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700312 DocComment("Return callback for " + method->name()).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800313 out << "using "
314 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700315 << "_cb = std::function<void(";
316 method->emitCppResultSignature(out, true /* specify namespaces */);
317 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800318 }
Andreas Huber881227d2016-08-02 14:20:21 -0700319
Andreas Huber3599d922016-08-09 10:42:57 -0700320 method->dumpAnnotations(out);
321
Steven Moreland49bad8d2018-05-17 15:45:26 -0700322 method->emitDocComment(out);
323
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700324 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700325 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700326 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700327 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700328 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700329 }
330
331 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700332 << "(";
333 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700334 out << ")";
335 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800336 if (!isIBase()) {
337 out << " override";
338 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700339 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700340 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700341 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700342 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700343 }
Steven Moreland40786312016-08-16 10:29:40 -0700344
Steven Moreland7645fbd2019-03-12 18:49:28 -0700345 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800346 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700347
Yifan Hong3d746092016-12-07 14:26:33 -0800348 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700349 DocComment(
350 "This performs a checked cast based on what the underlying implementation "
351 "actually is.")
352 .emit(out);
Yifan Hong200209c2017-03-29 03:39:09 -0700353 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800354 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700355 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800356 << superType->getCppArgumentType()
357 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700358 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700359 }
360
Yifan Hongc8934042016-11-17 17:10:52 -0800361 if (isIBase()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700362 out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800363 } else {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700364 out << "\n// helper methods for interactions with the hwservicemanager\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800365 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800366 }
Andreas Huber881227d2016-08-02 14:20:21 -0700367 }
368
Steven Moreland19f11b52017-05-12 18:22:21 -0700369 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700370 out.unindent();
371
Andreas Hubere3f769a2016-10-10 10:54:44 -0700372 out << "};\n\n";
373 }
374
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700375 out << "//\n";
376 out << "// type declarations for package\n";
377 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800378 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700379 out << "//\n";
380 out << "// type header definitions for package\n";
381 out << "//\n\n";
382 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700383
384 out << "\n";
385 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700386 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700387
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700388 out << "//\n";
389 out << "// global type declarations for package\n";
390 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800391 mRootScope.emitGlobalTypeDeclarations(out);
392
Andreas Huber881227d2016-08-02 14:20:21 -0700393 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700394}
395
Steven Moreland368e4602018-02-16 14:21:49 -0800396void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700397 const Interface *iface = getInterface();
398 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700399
Steven Moreland40786312016-08-16 10:29:40 -0700400 const std::string guard = makeHeaderGuard(klassName);
401
402 out << "#ifndef " << guard << "\n";
403 out << "#define " << guard << "\n\n";
404
Steven Moreland19f11b52017-05-12 18:22:21 -0700405 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700406
Steven Morelandee88eed2016-10-31 17:49:00 -0700407 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700408
409 for (const auto &item : mImportedNames) {
410 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800411 generateCppPackageInclude(out, item, "hwtypes");
412 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800413 generateCppPackageInclude(out, item, item.getInterfaceStubName());
414 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700415 }
Steven Moreland40786312016-08-16 10:29:40 -0700416 }
417
418 out << "\n";
419
Martijn Coenen93915102016-09-01 01:35:52 +0200420 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700421 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100422 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700423
424 out << "\n";
425
426 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700427
Steven Moreland368e4602018-02-16 14:21:49 -0800428 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700429
430 enterLeaveNamespace(out, false /* enter */);
431
432 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700433}
434
Steven Moreland58a20c72018-10-09 12:30:51 -0700435static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
436 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800437 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700438 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800439 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700440 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800441 const Interface &iface = static_cast<const Interface &>(arg->type());
442 out << iface.getCppStackType() << " " << wrappedName << ";\n";
443 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
444 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
445 out << wrappedName
446 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700447 << "::android::hardware::details::wrapPassthrough("
448 << name
449 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800450 out.sIf(wrappedName + " == nullptr", [&] {
451 // Fatal error. Happens when the BsFoo class is not found in the binary
452 // or any dynamic libraries.
453 handleError();
454 }).endl();
455 }).sElse([&] {
456 out << wrappedName << " = " << name << ";\n";
457 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700458
459 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800460}
461
Steven Moreland616cf4d2018-10-02 13:52:18 -0700462void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700463 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700464
Steven Moreland58a20c72018-10-09 12:30:51 -0700465 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700466 out.indent();
467
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800468 if (method->isHidlReserved()
469 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
470 method->cppImpl(IMPL_PASSTHROUGH, out);
471 out.unindent();
472 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800473 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800474 }
475
Steven Moreland69e7c702016-09-09 11:16:32 -0700476 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700477 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700478
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700479 generateCppInstrumentationCall(
480 out,
481 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700482 method,
483 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700484
Steven Moreland58a20c72018-10-09 12:30:51 -0700485 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800486 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700487 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800488 out << "return ::android::hardware::Status::fromExceptionCode(\n";
489 out.indent(2, [&] {
490 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800491 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800492 });
493 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700494
495 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800496 }
497
Steven Moreland58a20c72018-10-09 12:30:51 -0700498 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700499 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700500
501 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700502 out << "addOnewayTask([mImpl = this->mImpl\n"
503 << "#ifdef __ANDROID_DEBUGGABLE__\n"
504 ", mEnableInstrumentation = this->mEnableInstrumentation, "
505 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
506 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700507 for (const std::string& arg : wrappedArgNames) {
508 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700509 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700510 out << "] {\n";
511 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700512 }
513
514 out << "mImpl->"
515 << method->name()
516 << "(";
517
Yifan Hong932464e2017-03-30 15:40:22 -0700518 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800519 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700520 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700521
522 std::function<void(void)> kHandlePassthroughError = [&] {
523 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
524 out.indent(2, [&] {
525 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
526 << "\"Cannot wrap passthrough interface.\");\n";
527 });
528 };
529
Steven Moreland69e7c702016-09-09 11:16:32 -0700530 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700531 // never true if oneway since oneway methods don't return values
532
Steven Moreland69e7c702016-09-09 11:16:32 -0700533 if (!method->args().empty()) {
534 out << ", ";
535 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800536 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700537 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800538 out << "const auto &_hidl_out_"
539 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700540 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800541
542 out << ") {\n";
543 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700544 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800545 out,
546 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700547 method,
548 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800549
Steven Moreland58a20c72018-10-09 12:30:51 -0700550 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800551 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700552 wrappedOutNames.push_back(
553 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800554 }
555
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800556 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700557 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
558 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800559 out << ");\n";
560 out.unindent();
561 out << "});\n\n";
562 } else {
563 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700564
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800565 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700566 const std::string outName = "_hidl_out_" + elidedReturn->name();
567
568 out << elidedReturn->type().getCppResultType() << " " << outName
569 << " = _hidl_return;\n";
570 out << "(void) " << outName << ";\n";
571
572 const std::string wrappedName =
573 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
574
575 if (outName != wrappedName) {
576 // update the original value since it is used by generateCppInstrumentationCall
577 out << outName << " = " << wrappedName << ";\n\n";
578
579 // update the value to be returned
580 out << "_hidl_return = " << outName << "\n;";
581 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800582 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700583 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800584 out,
585 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700586 method,
587 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700588 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700589
590 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700591 out.unindent();
592 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700593 } else {
594 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700595 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700596
597 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700598
599 out.unindent();
600 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700601}
602
Steven Moreland368e4602018-02-16 14:21:49 -0800603void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700604 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700605
Yifan Hong10fe0b52016-10-19 14:20:17 -0700606 const Interface *prevIterface = nullptr;
607 for (const auto &tuple : iface->allMethodsFromRoot()) {
608 const Method *method = tuple.method();
609 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700610
Steven Morelandf16c5c02017-07-31 16:50:06 -0700611 if (!includeParent && superInterface != iface) {
612 continue;
613 }
614
Yifan Hong10fe0b52016-10-19 14:20:17 -0700615 if(prevIterface != superInterface) {
616 if (prevIterface != nullptr) {
617 out << "\n";
618 }
619 out << "// Methods from "
620 << superInterface->fullName()
621 << " follow.\n";
622 prevIterface = superInterface;
623 }
Steven Moreland368e4602018-02-16 14:21:49 -0800624 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700625 }
626
Yifan Hong10fe0b52016-10-19 14:20:17 -0700627 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700628}
629
Steven Moreland0b843772017-06-23 16:33:38 -0700630void AST::generateTemplatizationLink(Formatter& out) const {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700631 DocComment("The pure class is what this class wraps.").emit(out);
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700632 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700633}
634
Steven Moreland1a52e822017-07-27 13:56:29 -0700635void AST::generateCppTag(Formatter& out, const std::string& tag) const {
636 out << "typedef " << tag << " _hidl_tag;\n\n";
637}
638
Steven Moreland368e4602018-02-16 14:21:49 -0800639void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800640 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700641
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700642 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800643 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700644 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700645
646 out << "#ifndef " << guard << "\n";
647 out << "#define " << guard << "\n\n";
648
Yifan Hongeefe4f22017-01-04 15:32:42 -0800649 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700650
Steven Morelandee88eed2016-10-31 17:49:00 -0700651 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700652
653 enterLeaveNamespace(out, true /* enter */);
654 out << "\n";
655
656 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800657 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100658 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800659 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000660 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100661 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800662 out << " : public "
663 << gIBaseFqName.getInterfaceStubFqName().cppName()
664 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100665 }
Andreas Huber881227d2016-08-02 14:20:21 -0700666
667 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800668 out << "explicit "
669 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700670 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100671 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800672 out << "explicit "
673 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700674 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800675 << " const std::string& HidlInstrumentor_package,"
676 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700677 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000678 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700679 out << "::android::status_t onTransact(\n";
680 out.indent();
681 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700682 out << "uint32_t _hidl_code,\n";
683 out << "const ::android::hardware::Parcel &_hidl_data,\n";
684 out << "::android::hardware::Parcel *_hidl_reply,\n";
685 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700686 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700687 out.unindent();
688 out.unindent();
689
Steven Moreland0b843772017-06-23 16:33:38 -0700690 out.endl();
691 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700692 DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
693 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700694 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700695
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800696 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700697
Steven Moreland368e4602018-02-16 14:21:49 -0800698 generateMethods(out,
699 [&](const Method* method, const Interface*) {
700 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
701 return;
702 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700703
Steven Moreland368e4602018-02-16 14:21:49 -0800704 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700705
Steven Moreland368e4602018-02-16 14:21:49 -0800706 out.indent(2,
707 [&] {
708 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
709 << "const ::android::hardware::Parcel &_hidl_data,\n"
710 << "::android::hardware::Parcel *_hidl_reply,\n"
711 << "TransactCallback _hidl_cb);\n";
712 })
713 .endl()
714 .endl();
715 },
716 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700717
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100718 out.unindent();
719 out << "private:\n";
720 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800721
Steven Moreland368e4602018-02-16 14:21:49 -0800722 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800723 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800724 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800725 }
726 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700727 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800728
729 if (elidedReturn == nullptr && returnsValue) {
730 out << "using " << method->name() << "_cb = "
731 << iface->fqName().cppName()
732 << "::" << method->name() << "_cb;\n";
733 }
734 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800735 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800736 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800737
Steven Moreland19f11b52017-05-12 18:22:21 -0700738 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700739 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700740 out << "};\n\n";
741
742 enterLeaveNamespace(out, false /* enter */);
743
744 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700745}
746
Steven Moreland368e4602018-02-16 14:21:49 -0800747void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700748 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700749 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800750 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700751 }
752
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700753 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800754 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800755 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700756
757 out << "#ifndef " << guard << "\n";
758 out << "#define " << guard << "\n\n";
759
Martijn Coenen115d4282016-12-19 05:14:04 +0100760 out << "#include <hidl/HidlTransportSupport.h>\n\n";
761
Andreas Huber881227d2016-08-02 14:20:21 -0700762 std::vector<std::string> packageComponents;
763 getPackageAndVersionComponents(
764 &packageComponents, false /* cpp_compatible */);
765
Yifan Hongeefe4f22017-01-04 15:32:42 -0800766 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700767 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700768
769 enterLeaveNamespace(out, true /* enter */);
770 out << "\n";
771
772 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800773 << proxyName
774 << " : public ::android::hardware::BpInterface<"
775 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000776 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700777
778 out.indent();
779
Yifan Hongeefe4f22017-01-04 15:32:42 -0800780 out << "explicit "
781 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700782 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700783 << "\n\n";
784
Steven Moreland0b843772017-06-23 16:33:38 -0700785 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700786 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
787 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700788 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700789
Yifan Hong10fe0b52016-10-19 14:20:17 -0700790 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700791
Steven Moreland368e4602018-02-16 14:21:49 -0800792 generateMethods(
793 out,
794 [&](const Method* method, const Interface*) {
795 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
796 return;
797 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700798
Steven Moreland368e4602018-02-16 14:21:49 -0800799 out << "static ";
800 method->generateCppReturnType(out);
801 out << " _hidl_" << method->name() << "("
802 << "::android::hardware::IInterface* _hidl_this, "
803 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700804
Steven Moreland368e4602018-02-16 14:21:49 -0800805 if (!method->hasEmptyCppArgSignature()) {
806 out << ", ";
807 }
808 method->emitCppArgSignature(out);
809 out << ");\n";
810 },
811 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700812
Steven Moreland368e4602018-02-16 14:21:49 -0800813 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700814 method->generateCppSignature(out);
815 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700816 });
Steven Moreland9c387612016-09-07 09:54:26 -0700817
Andreas Huber881227d2016-08-02 14:20:21 -0700818 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100819 out << "private:\n";
820 out.indent();
821 out << "std::mutex _hidl_mMutex;\n"
822 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
823 << " _hidl_mDeathRecipients;\n";
824 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700825 out << "};\n\n";
826
827 enterLeaveNamespace(out, false /* enter */);
828
829 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700830}
831
Steven Moreland368e4602018-02-16 14:21:49 -0800832void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700833 std::string baseName = getBaseName();
834 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700835
Steven Morelanda885d252017-09-25 18:44:43 -0700836 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700837
Steven Moreland623c0042017-01-13 14:42:29 -0800838 out << "#define LOG_TAG \""
839 << mPackage.string() << "::" << baseName
840 << "\"\n\n";
841
Steven Moreland5add34d2018-11-08 16:31:30 -0800842 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100843 out << "#include <cutils/trace.h>\n";
844 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700845 out << "#include <hidl/Static.h>\n";
846 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700847 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700848 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700849 // This is a no-op for IServiceManager itself.
850 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
851
Yifan Hongeefe4f22017-01-04 15:32:42 -0800852 generateCppPackageInclude(out, mPackage, iface->getProxyName());
853 generateCppPackageInclude(out, mPackage, iface->getStubName());
854 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700855
856 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700857 generateCppPackageInclude(out,
858 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800859 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700860 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800861
862 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700863 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700864 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800865 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700866 }
867
868 out << "\n";
869
870 enterLeaveNamespace(out, true /* enter */);
871 out << "\n";
872
Steven Moreland368e4602018-02-16 14:21:49 -0800873 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700874
Steven Moreland368e4602018-02-16 14:21:49 -0800875 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700876 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700877
878 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800879 out << "const char* "
880 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700881 << "::descriptor(\""
882 << iface->fqName().string()
883 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800884 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100885 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800886 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800887 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800888 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800889 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800890 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800891 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800892 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800893 out << "return new "
894 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700895 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800896 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800897 << " *>(iIntf));\n";
898 });
Yifan Hongb04de382017-02-06 15:31:52 -0800899 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800900 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800901 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800902 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800903 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800904 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800905 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800906 << gIBaseFqName.cppName()
907 << "> {\n";
908 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800909 out << "return new "
910 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700911 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800912 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800913 << " *>(iIntf));\n";
914 });
Yifan Hongb04de382017-02-06 15:31:52 -0800915 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800916 });
Yifan Hong158655a2016-11-08 12:34:07 -0800917 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100918 out << "};\n\n";
919 out << "__attribute__((destructor))";
920 out << "static void static_destructor() {\n";
921 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800922 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100923 << iface->localName()
924 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800925 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100926 << iface->localName()
927 << "::descriptor);\n";
928 });
929 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800930
Steven Moreland368e4602018-02-16 14:21:49 -0800931 generateInterfaceSource(out);
932 generateProxySource(out, iface->fqName());
933 generateStubSource(out, iface);
934 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700935
Yifan Hongc8934042016-11-17 17:10:52 -0800936 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800937 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800938 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800939 std::string package = iface->fqName().package()
940 + iface->fqName().atVersion();
941
Yifan Hongeefe4f22017-01-04 15:32:42 -0800942 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800943 }
Steven Moreland40786312016-08-16 10:29:40 -0700944 }
945
Andreas Huber6755e9d2017-04-06 11:09:07 -0700946 HidlTypeAssertion::EmitAll(out);
947 out << "\n";
948
Andreas Huber881227d2016-08-02 14:20:21 -0700949 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700950}
951
Steven Moreland368e4602018-02-16 14:21:49 -0800952void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
953 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700954}
955
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700956void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
957 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700958 if (args.empty()) {
959 return;
960 }
961
962 for (const auto &arg : args) {
963 const Type &type = arg->type();
964
Yifan Hong3b320f82016-11-01 15:15:54 -0700965 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700966 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700967 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700968 << ";\n";
969 }
970
971 out << "\n";
972}
973
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700974void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
975 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
976 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700977 const Type &type = arg->type();
978
Andreas Huber881227d2016-08-02 14:20:21 -0700979 type.emitReaderWriter(
980 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700981 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700982 parcelObj,
983 parcelObjIsPointer,
984 isReader,
985 mode);
986}
987
Steven Moreland368e4602018-02-16 14:21:49 -0800988void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
989 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700990 method->generateCppSignature(out,
991 klassName,
992 true /* specify namespaces */);
993
Martijn Coenen115d4282016-12-19 05:14:04 +0100994 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -0700995 out.block([&] {
996 method->cppImpl(IMPL_PROXY, out);
997 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -0800998 return;
Martijn Coenen115d4282016-12-19 05:14:04 +0100999 }
1000
Steven Morelandf16c5c02017-07-31 16:50:06 -07001001 out.block([&] {
1002 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001003 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001004
1005 method->generateCppReturnType(out);
1006
1007 out << " _hidl_out = "
1008 << superInterface->fqName().cppNamespace()
1009 << "::"
1010 << superInterface->getProxyName()
1011 << "::_hidl_"
1012 << method->name()
1013 << "(this, this";
1014
1015 if (!method->hasEmptyCppArgSignature()) {
1016 out << ", ";
1017 }
1018
1019 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1020 out << arg->name();
1021 });
1022
1023 if (returnsValue && elidedReturn == nullptr) {
1024 if (!method->args().empty()) {
1025 out << ", ";
1026 }
1027 out << "_hidl_cb";
1028 }
1029
1030 out << ");\n\n";
1031
1032 out << "return _hidl_out;\n";
1033 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001034}
1035
Steven Moreland368e4602018-02-16 14:21:49 -08001036void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001037 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001038 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001039 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001040 }
1041
1042 method->generateCppReturnType(out);
1043
1044 out << klassName
1045 << "::_hidl_"
1046 << method->name()
1047 << "("
1048 << "::android::hardware::IInterface *_hidl_this, "
1049 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1050
1051 if (!method->hasEmptyCppArgSignature()) {
1052 out << ", ";
1053 }
1054
1055 method->emitCppArgSignature(out);
1056 out << ") {\n";
1057
1058 out.indent();
1059
1060 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1061 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1062 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1063 out << "#else\n";
1064 out << "(void) _hidl_this_instrumentor;\n";
1065 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1066
1067 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001068 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001069 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1070
Steven Moreland92a08a72017-07-31 14:57:37 -07001071 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001072 out,
1073 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001074 method,
1075 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001076
1077 out << "::android::hardware::Parcel _hidl_data;\n";
1078 out << "::android::hardware::Parcel _hidl_reply;\n";
1079 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001080 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001081 out << "::android::hardware::Status _hidl_status;\n\n";
1082
Steven Moreland48cc6042019-04-30 11:28:56 -07001083 if (!hasCallback) {
1084 declareCppReaderLocals(
1085 out, method->results(), true /* forResults */);
1086 }
Yifan Hong068c5522016-10-31 14:07:25 -07001087
1088 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001089 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001090 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001091 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1092
Martijn Coenenfff73352017-01-04 16:36:31 +01001093 bool hasInterfaceArgument = false;
Steven Moreland8249f0a2019-05-28 17:25:27 -07001094
Yifan Hong068c5522016-10-31 14:07:25 -07001095 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001096 if (arg->type().isInterface()) {
1097 hasInterfaceArgument = true;
1098 }
Yifan Hong068c5522016-10-31 14:07:25 -07001099 emitCppReaderWriter(
1100 out,
1101 "_hidl_data",
1102 false /* parcelObjIsPointer */,
1103 arg,
1104 false /* reader */,
1105 Type::ErrorMode_Goto,
1106 false /* addPrefixToName */);
1107 }
1108
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001109 if (hasInterfaceArgument) {
1110 // Start binder threadpool to handle incoming transactions
1111 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1112 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001113 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001114 << method->getSerialId()
1115 << " /* "
1116 << method->name()
1117 << " */, _hidl_data, &_hidl_reply";
1118
1119 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001120 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001121 } else {
1122 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001123 }
Yifan Hong068c5522016-10-31 14:07:25 -07001124
Steven Moreland48cc6042019-04-30 11:28:56 -07001125 if (hasCallback) {
1126 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1127 out.indent();
1128 declareCppReaderLocals(
1129 out, method->results(), true /* forResults */);
1130 out.endl();
1131 } else {
1132 out << ");\n";
1133 out << "if (_hidl_transact_err != ::android::OK) \n";
1134 out.block([&] {
1135 out << "_hidl_err = _hidl_transact_err;\n";
1136 out << "goto _hidl_error;\n";
1137 }).endl().endl();
1138 }
Yifan Hong068c5522016-10-31 14:07:25 -07001139
1140 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001141 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001142
Steven Moreland48cc6042019-04-30 11:28:56 -07001143 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1144 Type::handleError(out, errorMode);
1145
1146 if (hasCallback) {
1147 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1148 } else {
1149 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1150 }
Yifan Hong068c5522016-10-31 14:07:25 -07001151
Yifan Hong068c5522016-10-31 14:07:25 -07001152 for (const auto &arg : method->results()) {
1153 emitCppReaderWriter(
1154 out,
1155 "_hidl_reply",
1156 false /* parcelObjIsPointer */,
1157 arg,
1158 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001159 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001160 true /* addPrefixToName */);
1161 }
1162
Yifan Hong068c5522016-10-31 14:07:25 -07001163 if (returnsValue && elidedReturn == nullptr) {
1164 out << "_hidl_cb(";
1165
Yifan Hong932464e2017-03-30 15:40:22 -07001166 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001167 if (arg->type().resultNeedsDeref()) {
1168 out << "*";
1169 }
1170 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001171 });
Yifan Hong068c5522016-10-31 14:07:25 -07001172
1173 out << ");\n\n";
1174 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001175 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001176
Steven Moreland92a08a72017-07-31 14:57:37 -07001177 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001178 out,
1179 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001180 method,
1181 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001182
Steven Moreland48cc6042019-04-30 11:28:56 -07001183 if (hasCallback) {
1184 out.unindent();
1185 out << "});\n";
1186 out << "if (_hidl_transact_err != ::android::OK) ";
1187 out.block([&] {
1188 out << "_hidl_err = _hidl_transact_err;\n";
1189 out << "goto _hidl_error;\n";
1190 }).endl().endl();
1191 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1192 }
1193
Yifan Hong068c5522016-10-31 14:07:25 -07001194 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001195 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001196 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001197 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1198 } else {
Yifan Hong068c5522016-10-31 14:07:25 -07001199 out << "return ::android::hardware::Return<void>();\n\n";
1200 }
1201
1202 out.unindent();
1203 out << "_hidl_error:\n";
1204 out.indent();
1205 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1206 out << "return ::android::hardware::Return<";
1207 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001208 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001209 } else {
1210 out << "void";
1211 }
1212 out << ">(_hidl_status);\n";
1213
1214 out.unindent();
1215 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001216}
1217
Steven Moreland368e4602018-02-16 14:21:49 -08001218void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001219 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001220
1221 out << klassName
1222 << "::"
1223 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001224 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001225
1226 out.indent();
1227 out.indent();
1228
1229 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001230 << "<"
1231 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001232 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001233 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001234 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001235 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001236 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001237 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001238
Andreas Huber881227d2016-08-02 14:20:21 -07001239 out.unindent();
1240 out.unindent();
1241 out << "}\n\n";
1242
Steven Moreland368e4602018-02-16 14:21:49 -08001243 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001244 [&](const Method* method, const Interface* superInterface) {
1245 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001246 },
1247 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001248
Steven Moreland368e4602018-02-16 14:21:49 -08001249 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1250 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001251 });
Andreas Huber881227d2016-08-02 14:20:21 -07001252}
1253
Steven Moreland368e4602018-02-16 14:21:49 -08001254void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001255 const std::string interfaceName = iface->localName();
1256 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001257
Steven Moreland40786312016-08-16 10:29:40 -07001258 out << klassName
1259 << "::"
1260 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001261 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001262
1263 out.indent();
1264 out.indent();
1265
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001266 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001267 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001268 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001269 out << ": "
1270 << gIBaseFqName.getInterfaceStubFqName().cppName()
1271 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001272 }
1273
1274 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001275 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001276 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001277 << "\") { \n";
1278 out.indent();
1279 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001280 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001281 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1282 out << "mSchedPolicy = prio.sched_policy;\n";
1283 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001284 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1285 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001286 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001287
1288 out.unindent();
1289 out.unindent();
1290 out << "}\n\n";
1291
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001292 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001293 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001294 // class properly.
1295 out << klassName
1296 << "::"
1297 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001298 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1299 << " const std::string &HidlInstrumentor_package,"
1300 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001301
1302 out.indent();
1303 out.indent();
1304
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001305 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001306 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001307 out.indent();
1308 out << "_hidl_mImpl = _hidl_impl;\n";
1309 out.unindent();
1310
1311 out.unindent();
1312 out.unindent();
1313 out << "}\n\n";
1314 }
1315
Steven Moreland57a89362017-07-21 19:29:54 +00001316 out << klassName << "::~" << klassName << "() ";
1317 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001318 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1319 })
1320 .endl()
1321 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001322
Steven Moreland368e4602018-02-16 14:21:49 -08001323 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001324 [&](const Method* method, const Interface* superInterface) {
1325 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001326 },
1327 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001328
Steven Moreland368e4602018-02-16 14:21:49 -08001329 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001330 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001331 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001332 }
1333 method->generateCppSignature(out, iface->getStubName());
1334 out << " ";
1335 out.block([&] {
1336 method->cppImpl(IMPL_STUB_IMPL, out);
1337 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001338 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001339
Andreas Huber881227d2016-08-02 14:20:21 -07001340 out << "::android::status_t " << klassName << "::onTransact(\n";
1341
1342 out.indent();
1343 out.indent();
1344
Iliyan Malchev549e2592016-08-10 08:59:12 -07001345 out << "uint32_t _hidl_code,\n"
1346 << "const ::android::hardware::Parcel &_hidl_data,\n"
1347 << "::android::hardware::Parcel *_hidl_reply,\n"
1348 << "uint32_t _hidl_flags,\n"
1349 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001350
1351 out.unindent();
1352
Iliyan Malchev549e2592016-08-10 08:59:12 -07001353 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001354 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001355 out.indent();
1356
Yifan Hong10fe0b52016-10-19 14:20:17 -07001357 for (const auto &tuple : iface->allMethodsFromRoot()) {
1358 const Method *method = tuple.method();
1359 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001360
Howard Chen71f289f2017-08-29 17:35:01 +08001361 if (!isIBase() && method->isHidlReserved()) {
1362 continue;
1363 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001364 out << "case "
1365 << method->getSerialId()
1366 << " /* "
1367 << method->name()
1368 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001369
Yifan Hong10fe0b52016-10-19 14:20:17 -07001370 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001371
Steven Moreland368e4602018-02-16 14:21:49 -08001372 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001373
1374 out.unindent();
1375 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001376 }
1377
1378 out << "default:\n{\n";
1379 out.indent();
1380
Martijn Coenen225bc922017-06-27 14:39:46 -07001381 if (iface->isIBase()) {
1382 out << "(void)_hidl_flags;\n";
1383 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1384 } else {
1385 out << "return ";
1386 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1387 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001388
Martijn Coenen225bc922017-06-27 14:39:46 -07001389 out.indent();
1390 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001391
Martijn Coenen225bc922017-06-27 14:39:46 -07001392 out << "_hidl_code, _hidl_data, _hidl_reply, "
1393 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001394
Martijn Coenen225bc922017-06-27 14:39:46 -07001395 out.unindent();
1396 out.unindent();
1397 }
Andreas Huber881227d2016-08-02 14:20:21 -07001398
1399 out.unindent();
1400 out << "}\n";
1401
1402 out.unindent();
1403 out << "}\n\n";
1404
Yifan Honga018ed52016-12-13 16:35:08 -08001405 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1406 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1407 out.indent(2, [&] {
1408 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1409 out << "_hidl_reply);\n";
1410 });
1411 });
Andreas Huber881227d2016-08-02 14:20:21 -07001412
Iliyan Malchev549e2592016-08-10 08:59:12 -07001413 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001414
1415 out.unindent();
1416 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001417}
1418
Steven Moreland368e4602018-02-16 14:21:49 -08001419void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1420 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001421 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1422 method->cppImpl(IMPL_STUB, out);
1423 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001424 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001425 }
1426
Steven Morelandf16c5c02017-07-31 16:50:06 -07001427 out << "_hidl_err = "
1428 << superInterface->fqName().cppNamespace()
1429 << "::"
1430 << superInterface->getStubName()
1431 << "::_hidl_"
1432 << method->name()
1433 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1434 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001435}
1436
Steven Moreland368e4602018-02-16 14:21:49 -08001437void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001438 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001439 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001440 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001441 }
1442
Steven Morelandf8197902018-01-30 15:38:37 -08001443 const std::string& klassName = fqName.getInterfaceStubName();
1444
Steven Morelandf16c5c02017-07-31 16:50:06 -07001445 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1446
1447 out.indent();
1448 out.indent();
1449
1450 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1451 << "const ::android::hardware::Parcel &_hidl_data,\n"
1452 << "::android::hardware::Parcel *_hidl_reply,\n"
1453 << "TransactCallback _hidl_cb) {\n";
1454
1455 out.unindent();
1456
1457 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1458 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1459 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1460 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1461
1462 out << "::android::status_t _hidl_err = ::android::OK;\n";
1463
Yifan Hongeefe4f22017-01-04 15:32:42 -08001464 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001465 << klassName
1466 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001467
Andreas Huber881227d2016-08-02 14:20:21 -07001468 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001469 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001470 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001471 out.unindent();
1472 out << "}\n\n";
1473
Andreas Huber5e44a292016-09-27 14:52:39 -07001474 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001475
Andreas Huber881227d2016-08-02 14:20:21 -07001476 for (const auto &arg : method->args()) {
1477 emitCppReaderWriter(
1478 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001479 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001480 false /* parcelObjIsPointer */,
1481 arg,
1482 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001483 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001484 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001485 }
1486
Steven Moreland92a08a72017-07-31 14:57:37 -07001487 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001488 out,
1489 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001490 method,
1491 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001492
Andreas Huber881227d2016-08-02 14:20:21 -07001493 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001494 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001495
1496 std::string callee;
1497
1498 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1499 callee = "_hidl_this";
1500 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001501 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001502 }
Andreas Huber881227d2016-08-02 14:20:21 -07001503
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001504 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001505 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001506 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001507 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001508 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001509 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001510 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001511
Yifan Hong932464e2017-03-30 15:40:22 -07001512 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001513 if (arg->type().resultNeedsDeref()) {
1514 out << "*";
1515 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001516 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001517 });
Andreas Huber881227d2016-08-02 14:20:21 -07001518
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001519 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001520
Yifan Hong859e53f2016-11-14 19:08:24 -08001521 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1522 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001523
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001524 elidedReturn->type().emitReaderWriter(
1525 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001526 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001527 "_hidl_reply",
1528 true, /* parcelObjIsPointer */
1529 false, /* isReader */
1530 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001531
Steven Moreland92a08a72017-07-31 14:57:37 -07001532 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001533 out,
1534 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001535 method,
1536 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001537
Iliyan Malchev549e2592016-08-10 08:59:12 -07001538 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001539 } else {
1540 if (returnsValue) {
1541 out << "bool _hidl_callbackCalled = false;\n\n";
1542 }
Andreas Huber881227d2016-08-02 14:20:21 -07001543
Steven Moreland30232dc2019-03-05 19:39:10 -08001544 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1545 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001546
Yifan Hong932464e2017-03-30 15:40:22 -07001547 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001548 if (arg->type().resultNeedsDeref()) {
1549 out << "*";
1550 }
1551
1552 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001553 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001554
1555 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001556 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001557 out << ", ";
1558 }
1559
1560 out << "[&](";
1561
Yifan Hong932464e2017-03-30 15:40:22 -07001562 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001563 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001564 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001565
1566 out << ") {\n";
1567 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001568 out << "if (_hidl_callbackCalled) {\n";
1569 out.indent();
1570 out << "LOG_ALWAYS_FATAL(\""
1571 << method->name()
1572 << ": _hidl_cb called a second time, but must be called once.\");\n";
1573 out.unindent();
1574 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001575 out << "_hidl_callbackCalled = true;\n\n";
1576
Yifan Hong859e53f2016-11-14 19:08:24 -08001577 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1578 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001579
1580 for (const auto &arg : method->results()) {
1581 emitCppReaderWriter(
1582 out,
1583 "_hidl_reply",
1584 true /* parcelObjIsPointer */,
1585 arg,
1586 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001587 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001588 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001589 }
1590
Steven Moreland92a08a72017-07-31 14:57:37 -07001591 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001592 out,
1593 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001594 method,
1595 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001596
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001597 out << "_hidl_cb(*_hidl_reply);\n";
1598
1599 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001600 out << "});\n\n";
1601 } else {
1602 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001603 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001604 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001605 out,
1606 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001607 method,
1608 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001609 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001610
Steven Moreland30232dc2019-03-05 19:39:10 -08001611 out << "_hidl_ret.assertOk();\n";
1612
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613 if (returnsValue) {
1614 out << "if (!_hidl_callbackCalled) {\n";
1615 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001616 out << "LOG_ALWAYS_FATAL(\""
1617 << method->name()
1618 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001619 out.unindent();
1620 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001621 } else {
1622 out << "::android::hardware::writeToParcel("
1623 << "::android::hardware::Status::ok(), "
1624 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001625 }
Andreas Huber881227d2016-08-02 14:20:21 -07001626 }
1627
Steven Morelandf16c5c02017-07-31 16:50:06 -07001628 out << "return _hidl_err;\n";
1629 out.unindent();
1630 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001631}
1632
Steven Moreland368e4602018-02-16 14:21:49 -08001633void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001634 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001635 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001636 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001637 }
1638
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001639 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001640 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001641
Yifan Hongeefe4f22017-01-04 15:32:42 -08001642 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001643
Steven Moreland69e7c702016-09-09 11:16:32 -07001644 const std::string guard = makeHeaderGuard(klassName);
1645
1646 out << "#ifndef " << guard << "\n";
1647 out << "#define " << guard << "\n\n";
1648
1649 std::vector<std::string> packageComponents;
1650 getPackageAndVersionComponents(
1651 &packageComponents, false /* cpp_compatible */);
1652
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001653 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001654 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001655 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001656
Steven Moreland19f11b52017-05-12 18:22:21 -07001657 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001658 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001659
Yifan Hong7a118f52016-12-07 11:21:15 -08001660 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001661 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001662
1663 enterLeaveNamespace(out, true /* enter */);
1664 out << "\n";
1665
1666 out << "struct "
1667 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001668 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001669 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001670
1671 out.indent();
1672 out << "explicit "
1673 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001674 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001675 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001676 << "> impl);\n";
1677
Steven Moreland0b843772017-06-23 16:33:38 -07001678 out.endl();
1679 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001680 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001681
Steven Moreland616cf4d2018-10-02 13:52:18 -07001682 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1683 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001684 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001685
Steven Moreland69e7c702016-09-09 11:16:32 -07001686 out.unindent();
1687 out << "private:\n";
1688 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001689 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001690
Neel Mehta19f79792019-05-21 13:39:32 -07001691 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001692
Neel Mehta19f79792019-05-21 13:39:32 -07001693 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001694
Neel Mehta19f79792019-05-21 13:39:32 -07001695 out << "::android::hardware::Return<void> addOnewayTask("
1696 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001697
1698 out.unindent();
1699
1700 out << "};\n\n";
1701
1702 enterLeaveNamespace(out, false /* enter */);
1703
1704 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001705}
1706
Steven Moreland368e4602018-02-16 14:21:49 -08001707void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001708 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001709
Yifan Hong2d7126b2016-10-20 15:12:57 -07001710 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001711 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001712
Steven Moreland368e4602018-02-16 14:21:49 -08001713 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001714 bool reserved = method->isHidlReserved();
1715
1716 if (!reserved) {
1717 out << "// no default implementation for: ";
1718 }
1719 method->generateCppSignature(out, iface->localName());
1720 if (reserved) {
1721 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001722 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001723 }).endl();
1724 }
1725
1726 out << "\n";
1727
Steven Moreland368e4602018-02-16 14:21:49 -08001728 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001729 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001730
Yifan Hong3d746092016-12-07 14:26:33 -08001731 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001732 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001733 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001734 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001735 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001736 << "::castFrom("
1737 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001738 << " parent, bool "
1739 << (iface == superType ? "/* emitError */" : "emitError")
1740 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001741 out.indent();
1742 if (iface == superType) {
1743 out << "return parent;\n";
1744 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001745 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001746 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001747 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001748 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001749 << ">(\n";
1750 out.indent();
1751 out.indent();
1752 out << "parent, \""
1753 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001754 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001755 out.unindent();
1756 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001757 }
Yifan Hong3d746092016-12-07 14:26:33 -08001758 out.unindent();
1759 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001760 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001761}
1762
Steven Moreland368e4602018-02-16 14:21:49 -08001763void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001764 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001765
Yifan Hongeefe4f22017-01-04 15:32:42 -08001766 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001767
Neel Mehta19f79792019-05-21 13:39:32 -07001768 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1769 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1770 << "\", \"" << iface->localName() << "\"), mImpl(impl) {\n";
1771
1772 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1773
Yifan Hong2cbc1472016-10-25 19:02:40 -07001774 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001775
Neel Mehta19f79792019-05-21 13:39:32 -07001776 out << "::android::hardware::Return<void> " << klassName
1777 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1778 out.indent();
1779 out << "if (!mOnewayQueue.push(fun)) {\n";
1780 out.indent();
1781 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1782 out.indent();
1783 out.indent();
1784 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1785 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1786 out.unindent();
1787 out.unindent();
1788 out.unindent();
1789 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001790
Neel Mehta19f79792019-05-21 13:39:32 -07001791 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001792
Neel Mehta19f79792019-05-21 13:39:32 -07001793 out.unindent();
1794 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001795}
1796
Steven Moreland92a08a72017-07-31 14:57:37 -07001797void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001798 InstrumentationEvent event,
1799 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001800 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001801 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001802 switch (event) {
1803 case SERVER_API_ENTRY:
1804 {
1805 out << "atrace_begin(ATRACE_TAG_HAL, \""
1806 << baseString + "::server\");\n";
1807 break;
1808 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001809 case PASSTHROUGH_ENTRY:
1810 {
1811 out << "atrace_begin(ATRACE_TAG_HAL, \""
1812 << baseString + "::passthrough\");\n";
1813 break;
1814 }
1815 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001816 case PASSTHROUGH_EXIT:
1817 {
1818 out << "atrace_end(ATRACE_TAG_HAL);\n";
1819 break;
1820 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001821 // client uses scope because of gotos
1822 // this isn't done for server because the profiled code isn't alone in its scope
1823 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1824 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001825 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1826 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001827 break;
1828 }
1829 case CLIENT_API_EXIT:
1830 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001831 default:
1832 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001833 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001834 }
1835 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001836}
1837
Steven Moreland92a08a72017-07-31 14:57:37 -07001838void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001839 Formatter &out,
1840 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001841 const Method *method,
1842 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001843 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001844
Steven Moreland30b76e92017-06-02 18:52:24 -07001845 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001846 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1847 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001848 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001849 std::string event_str = "";
1850 switch (event) {
1851 case SERVER_API_ENTRY:
1852 {
1853 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1854 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001855 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001856 << (arg->type().resultNeedsDeref() ? "" : "&")
1857 << arg->name()
1858 << ");\n";
1859 }
1860 break;
1861 }
1862 case SERVER_API_EXIT:
1863 {
1864 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001865 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001866 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001867 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001868 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001869 }
1870 break;
1871 }
1872 case CLIENT_API_ENTRY:
1873 {
1874 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1875 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001876 out << "_hidl_args.push_back((void *)&"
1877 << arg->name()
1878 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001879 }
1880 break;
1881 }
1882 case CLIENT_API_EXIT:
1883 {
1884 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1885 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001886 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001887 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001888 << "_hidl_out_"
1889 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001890 << ");\n";
1891 }
1892 break;
1893 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001894 case PASSTHROUGH_ENTRY:
1895 {
1896 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1897 for (const auto &arg : method->args()) {
1898 out << "_hidl_args.push_back((void *)&"
1899 << arg->name()
1900 << ");\n";
1901 }
1902 break;
1903 }
1904 case PASSTHROUGH_EXIT:
1905 {
1906 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001907 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001908 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001909 << arg->name()
1910 << ");\n";
1911 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001912 break;
1913 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001914 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001915 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001916 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001917 }
1918 }
1919
Steven Moreland1ab31442016-11-03 18:37:51 -07001920 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001921 out.indent();
1922 out << "callback("
1923 << event_str
1924 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001925 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001926 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001927 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001928 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001929 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001930 << "\", \""
1931 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001932 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001933 out.unindent();
1934 out << "}\n";
1935 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001936 out << "}\n";
1937 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001938}
1939
Andreas Huber881227d2016-08-02 14:20:21 -07001940} // namespace android