blob: 597a2278fa0469d9ff9cc8dcb5490f309a5232ef [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 }
90 } else {
91 for (auto it = packageComponents.rbegin();
92 it != packageComponents.rend();
93 ++it) {
94 out << "} // namespace " << *it << "\n";
95 }
96 }
97}
98
Steven Moreland038903b2017-03-30 12:11:24 -070099static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
100 const std::string functionName = isTry ? "tryGetService" : "getService";
101
Steven Moreland7645fbd2019-03-12 18:49:28 -0700102 if (isTry) {
103 DocComment(
104 "This gets the service of this type with the specified instance name. If the\n"
105 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
106 "device, this will return nullptr. This is useful when you don't want to block\n"
107 "during device boot. If getStub is true, this will try to return an unwrapped\n"
108 "passthrough implementation in the same process. This is useful when getting an\n"
109 "implementation from the same partition/compilation group.\n\n"
110 "In general, prefer getService(std::string,bool)")
111 .emit(out);
112 } else {
113 DocComment(
114 "This gets the service of this type with the specified instance name. If the\n"
115 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
116 "nullptr. If the service is not available, this will wait for the service to\n"
117 "become available. If the service is a lazy service, this will start the service\n"
118 "and return when it becomes available. If getStub is true, this will try to\n"
119 "return an unwrapped passthrough implementation in the same process. This is\n"
120 "useful when getting an implementation from the same partition/compilation group.")
121 .emit(out);
122 }
Steven Moreland038903b2017-03-30 12:11:24 -0700123 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800124 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700125 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700126 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800127 << "const char serviceName[], bool getStub=false)"
128 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700129 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700130 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700131 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800132 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
133 // without c_str the std::string constructor is ambiguous
134 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700135 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700136 DocComment("Calls " + functionName +
137 "(\"default\", bool). This is the recommended instance name for singleton services.")
138 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700139 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
140 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
141}
142
143static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
144 declareGetService(out, interfaceName, true /* isTry */);
145 declareGetService(out, interfaceName, false /* isTry */);
146
Steven Moreland7645fbd2019-03-12 18:49:28 -0700147 DocComment(
148 "Registers a service with the service manager. For Trebilized devices, the service\n"
149 "must also be in the VINTF manifest.")
150 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700151 out << "__attribute__ ((warn_unused_result))"
152 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700153 DocComment("Registers for notifications for when a service is registered.").emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800154 out << "static bool registerForNotifications(\n";
155 out.indent(2, [&] {
156 out << "const std::string &serviceName,\n"
157 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
158 << "&notification);\n";
159 });
160
161}
162
Steven Moreland038903b2017-03-30 12:11:24 -0700163static void implementGetService(Formatter &out,
164 const FQName &fqName,
165 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800166
167 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700168 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800169
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700170 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000171 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800172 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700173 out << "return ::android::hardware::details::getServiceInternal<"
174 << fqName.getInterfaceProxyName()
175 << ">(serviceName, "
176 << (!isTry ? "true" : "false") // retry
177 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800178 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700179}
180
181static void implementServiceManagerInteractions(Formatter &out,
182 const FQName &fqName, const std::string &package) {
183
184 const std::string interfaceName = fqName.getInterfaceName();
185
186 implementGetService(out, fqName, true /* isTry */);
187 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800188
Yifan Hongeefe4f22017-01-04 15:32:42 -0800189 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800190 << "const std::string &serviceName) ";
191 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700192 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800193 }).endl().endl();
194
Yifan Hongeefe4f22017-01-04 15:32:42 -0800195 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800196 out.indent(2, [&] {
197 out << "const std::string &serviceName,\n"
198 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
199 << "&notification) ";
200 });
201 out.block([&] {
202 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
203 out.indent(2, [&] {
204 out << "= ::android::hardware::defaultServiceManager();\n";
205 });
206 out.sIf("sm == nullptr", [&] {
207 out << "return false;\n";
208 }).endl();
209 out << "::android::hardware::Return<bool> success =\n";
210 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800211 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800212 out.indent(2, [&] {
213 out << "serviceName, notification);\n";
214 });
215 });
216 out << "return success.isOk() && success;\n";
217 }).endl().endl();
218}
219
Steven Moreland368e4602018-02-16 14:21:49 -0800220void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700221 const Interface *iface = getInterface();
222 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700223 const std::string guard = makeHeaderGuard(ifaceName);
224
225 out << "#ifndef " << guard << "\n";
226 out << "#define " << guard << "\n\n";
227
Andreas Huber737080b2016-08-02 15:38:04 -0700228 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700229 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700230 }
231
232 if (!mImportedNames.empty()) {
233 out << "\n";
234 }
235
Steven Moreland19f11b52017-05-12 18:22:21 -0700236 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800237 if (isIBase()) {
238 out << "// skipped #include IServiceNotification.h\n\n";
239 } else {
240 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
241 }
Steven Moreland0693f312016-11-09 15:06:14 -0800242 }
243
Yifan Hongc8934042016-11-17 17:10:52 -0800244 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700245 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700246
Steven Moreland19f11b52017-05-12 18:22:21 -0700247 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200248 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700249 }
250
Martijn Coenenaf712c02016-11-16 15:26:27 +0100251 out << "#include <utils/NativeHandle.h>\n";
252 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700253
254 enterLeaveNamespace(out, true /* enter */);
255 out << "\n";
256
Steven Moreland19f11b52017-05-12 18:22:21 -0700257 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700258 iface->emitDocComment(out);
259
Andreas Huber881227d2016-08-02 14:20:21 -0700260 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700261 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700262
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700263 const Interface *superType = iface->superType();
264
Yi Kong56758da2018-07-24 16:21:37 -0700265 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800266 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700267 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000268 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700269 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700270 }
271
272 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700273
274 out.indent();
275
Steven Moreland7645fbd2019-03-12 18:49:28 -0700276 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.")
277 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700278 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700279
Steven Moreland7645fbd2019-03-12 18:49:28 -0700280 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"")
281 .emit(out);
282 out << "static const char* descriptor;\n\n";
283
Steven Moreland70cb55e2019-03-12 17:20:54 -0700284 iface->emitTypeDeclarations(out);
285 } else {
286 mRootScope.emitTypeDeclarations(out);
287 }
Andreas Huber881227d2016-08-02 14:20:21 -0700288
Steven Moreland19f11b52017-05-12 18:22:21 -0700289 if (iface) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700290 DocComment(
291 "Returns whether this object's implementation is outside of the current process.")
292 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800293 out << "virtual bool isRemote() const ";
294 if (!isIBase()) {
295 out << "override ";
296 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700297 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800298
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700299 for (const auto& tuple : iface->allMethodsFromRoot()) {
300 const Method* method = tuple.method();
301
Andreas Huber881227d2016-08-02 14:20:21 -0700302 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700303
Andreas Huber881227d2016-08-02 14:20:21 -0700304 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700305 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800306
307 if (elidedReturn == nullptr && returnsValue) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700308 DocComment("Return callback for " + method->name()).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800309 out << "using "
310 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700311 << "_cb = std::function<void(";
312 method->emitCppResultSignature(out, true /* specify namespaces */);
313 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800314 }
Andreas Huber881227d2016-08-02 14:20:21 -0700315
Andreas Huber3599d922016-08-09 10:42:57 -0700316 method->dumpAnnotations(out);
317
Steven Moreland49bad8d2018-05-17 15:45:26 -0700318 method->emitDocComment(out);
319
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700320 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700321 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700322 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700323 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700324 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700325 }
326
327 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700328 << "(";
329 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700330 out << ")";
331 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800332 if (!isIBase()) {
333 out << " override";
334 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700335 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700336 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700337 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700338 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700339 }
Steven Moreland40786312016-08-16 10:29:40 -0700340
Steven Moreland7645fbd2019-03-12 18:49:28 -0700341 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800342 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700343
Yifan Hong3d746092016-12-07 14:26:33 -0800344 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700345 DocComment(
346 "This performs a checked cast based on what the underlying implementation "
347 "actually is.")
348 .emit(out);
Yifan Hong200209c2017-03-29 03:39:09 -0700349 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800350 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700351 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800352 << superType->getCppArgumentType()
353 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700354 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700355 }
356
Yifan Hongc8934042016-11-17 17:10:52 -0800357 if (isIBase()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700358 out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800359 } else {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700360 out << "\n// helper methods for interactions with the hwservicemanager\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800361 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800362 }
Andreas Huber881227d2016-08-02 14:20:21 -0700363 }
364
Steven Moreland19f11b52017-05-12 18:22:21 -0700365 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700366 out.unindent();
367
Andreas Hubere3f769a2016-10-10 10:54:44 -0700368 out << "};\n\n";
369 }
370
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700371 out << "//\n";
372 out << "// type declarations for package\n";
373 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800374 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700375 out << "//\n";
376 out << "// type header definitions for package\n";
377 out << "//\n\n";
378 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700379
380 out << "\n";
381 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700382 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700383
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700384 out << "//\n";
385 out << "// global type declarations for package\n";
386 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800387 mRootScope.emitGlobalTypeDeclarations(out);
388
Andreas Huber881227d2016-08-02 14:20:21 -0700389 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700390}
391
Steven Moreland368e4602018-02-16 14:21:49 -0800392void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700393 const Interface *iface = getInterface();
394 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700395
Steven Moreland40786312016-08-16 10:29:40 -0700396 const std::string guard = makeHeaderGuard(klassName);
397
398 out << "#ifndef " << guard << "\n";
399 out << "#define " << guard << "\n\n";
400
Steven Moreland19f11b52017-05-12 18:22:21 -0700401 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700402
Steven Morelandee88eed2016-10-31 17:49:00 -0700403 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700404
405 for (const auto &item : mImportedNames) {
406 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800407 generateCppPackageInclude(out, item, "hwtypes");
408 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800409 generateCppPackageInclude(out, item, item.getInterfaceStubName());
410 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700411 }
Steven Moreland40786312016-08-16 10:29:40 -0700412 }
413
414 out << "\n";
415
Martijn Coenen93915102016-09-01 01:35:52 +0200416 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700417 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100418 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700419
420 out << "\n";
421
422 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700423
Steven Moreland368e4602018-02-16 14:21:49 -0800424 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700425
426 enterLeaveNamespace(out, false /* enter */);
427
428 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700429}
430
Steven Moreland58a20c72018-10-09 12:30:51 -0700431static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
432 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800433 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700434 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800435 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700436 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800437 const Interface &iface = static_cast<const Interface &>(arg->type());
438 out << iface.getCppStackType() << " " << wrappedName << ";\n";
439 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
440 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
441 out << wrappedName
442 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700443 << "::android::hardware::details::wrapPassthrough("
444 << name
445 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800446 out.sIf(wrappedName + " == nullptr", [&] {
447 // Fatal error. Happens when the BsFoo class is not found in the binary
448 // or any dynamic libraries.
449 handleError();
450 }).endl();
451 }).sElse([&] {
452 out << wrappedName << " = " << name << ";\n";
453 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700454
455 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800456}
457
Steven Moreland616cf4d2018-10-02 13:52:18 -0700458void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700459 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700460
Steven Moreland58a20c72018-10-09 12:30:51 -0700461 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700462 out.indent();
463
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800464 if (method->isHidlReserved()
465 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
466 method->cppImpl(IMPL_PASSTHROUGH, out);
467 out.unindent();
468 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800469 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800470 }
471
Steven Moreland69e7c702016-09-09 11:16:32 -0700472 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700473 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700474
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700475 generateCppInstrumentationCall(
476 out,
477 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700478 method,
479 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700480
Steven Moreland58a20c72018-10-09 12:30:51 -0700481 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800482 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700483 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800484 out << "return ::android::hardware::Status::fromExceptionCode(\n";
485 out.indent(2, [&] {
486 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800487 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800488 });
489 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700490
491 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800492 }
493
Steven Moreland58a20c72018-10-09 12:30:51 -0700494 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700495 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700496
497 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700498 out << "addOnewayTask([mImpl = this->mImpl\n"
499 << "#ifdef __ANDROID_DEBUGGABLE__\n"
500 ", mEnableInstrumentation = this->mEnableInstrumentation, "
501 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
502 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700503 for (const std::string& arg : wrappedArgNames) {
504 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700505 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700506 out << "] {\n";
507 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700508 }
509
510 out << "mImpl->"
511 << method->name()
512 << "(";
513
Yifan Hong932464e2017-03-30 15:40:22 -0700514 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800515 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700516 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700517
518 std::function<void(void)> kHandlePassthroughError = [&] {
519 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
520 out.indent(2, [&] {
521 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
522 << "\"Cannot wrap passthrough interface.\");\n";
523 });
524 };
525
Steven Moreland69e7c702016-09-09 11:16:32 -0700526 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700527 // never true if oneway since oneway methods don't return values
528
Steven Moreland69e7c702016-09-09 11:16:32 -0700529 if (!method->args().empty()) {
530 out << ", ";
531 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800532 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700533 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800534 out << "const auto &_hidl_out_"
535 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700536 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800537
538 out << ") {\n";
539 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700540 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800541 out,
542 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700543 method,
544 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800545
Steven Moreland58a20c72018-10-09 12:30:51 -0700546 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800547 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700548 wrappedOutNames.push_back(
549 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800550 }
551
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800552 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700553 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
554 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800555 out << ");\n";
556 out.unindent();
557 out << "});\n\n";
558 } else {
559 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700560
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800561 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700562 const std::string outName = "_hidl_out_" + elidedReturn->name();
563
564 out << elidedReturn->type().getCppResultType() << " " << outName
565 << " = _hidl_return;\n";
566 out << "(void) " << outName << ";\n";
567
568 const std::string wrappedName =
569 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
570
571 if (outName != wrappedName) {
572 // update the original value since it is used by generateCppInstrumentationCall
573 out << outName << " = " << wrappedName << ";\n\n";
574
575 // update the value to be returned
576 out << "_hidl_return = " << outName << "\n;";
577 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800578 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700579 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800580 out,
581 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700582 method,
583 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700584 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700585
586 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700587 out.unindent();
588 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700589 } else {
590 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700591 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700592
593 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700594
595 out.unindent();
596 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700597}
598
Steven Moreland368e4602018-02-16 14:21:49 -0800599void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700600 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700601
Yifan Hong10fe0b52016-10-19 14:20:17 -0700602 const Interface *prevIterface = nullptr;
603 for (const auto &tuple : iface->allMethodsFromRoot()) {
604 const Method *method = tuple.method();
605 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700606
Steven Morelandf16c5c02017-07-31 16:50:06 -0700607 if (!includeParent && superInterface != iface) {
608 continue;
609 }
610
Yifan Hong10fe0b52016-10-19 14:20:17 -0700611 if(prevIterface != superInterface) {
612 if (prevIterface != nullptr) {
613 out << "\n";
614 }
615 out << "// Methods from "
616 << superInterface->fullName()
617 << " follow.\n";
618 prevIterface = superInterface;
619 }
Steven Moreland368e4602018-02-16 14:21:49 -0800620 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700621 }
622
Yifan Hong10fe0b52016-10-19 14:20:17 -0700623 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700624}
625
Steven Moreland0b843772017-06-23 16:33:38 -0700626void AST::generateTemplatizationLink(Formatter& out) const {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700627 DocComment("The pure class is what this class wraps.").emit(out);
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700628 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700629}
630
Steven Moreland1a52e822017-07-27 13:56:29 -0700631void AST::generateCppTag(Formatter& out, const std::string& tag) const {
632 out << "typedef " << tag << " _hidl_tag;\n\n";
633}
634
Steven Moreland368e4602018-02-16 14:21:49 -0800635void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800636 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700637
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700638 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800639 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700640 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700641
642 out << "#ifndef " << guard << "\n";
643 out << "#define " << guard << "\n\n";
644
Yifan Hongeefe4f22017-01-04 15:32:42 -0800645 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700646
Steven Morelandee88eed2016-10-31 17:49:00 -0700647 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700648
649 enterLeaveNamespace(out, true /* enter */);
650 out << "\n";
651
652 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800653 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100654 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800655 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000656 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100657 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800658 out << " : public "
659 << gIBaseFqName.getInterfaceStubFqName().cppName()
660 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100661 }
Andreas Huber881227d2016-08-02 14:20:21 -0700662
663 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800664 out << "explicit "
665 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700666 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100667 << "\n";
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,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800671 << " const std::string& HidlInstrumentor_package,"
672 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700673 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000674 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700675 out << "::android::status_t onTransact(\n";
676 out.indent();
677 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700678 out << "uint32_t _hidl_code,\n";
679 out << "const ::android::hardware::Parcel &_hidl_data,\n";
680 out << "::android::hardware::Parcel *_hidl_reply,\n";
681 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700682 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700683 out.unindent();
684 out.unindent();
685
Steven Moreland0b843772017-06-23 16:33:38 -0700686 out.endl();
687 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700688 DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
689 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700690 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700691
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800692 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700693
Steven Moreland368e4602018-02-16 14:21:49 -0800694 generateMethods(out,
695 [&](const Method* method, const Interface*) {
696 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
697 return;
698 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700699
Steven Moreland368e4602018-02-16 14:21:49 -0800700 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700701
Steven Moreland368e4602018-02-16 14:21:49 -0800702 out.indent(2,
703 [&] {
704 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
705 << "const ::android::hardware::Parcel &_hidl_data,\n"
706 << "::android::hardware::Parcel *_hidl_reply,\n"
707 << "TransactCallback _hidl_cb);\n";
708 })
709 .endl()
710 .endl();
711 },
712 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700713
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100714 out.unindent();
715 out << "private:\n";
716 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800717
Steven Moreland368e4602018-02-16 14:21:49 -0800718 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800719 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800720 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800721 }
722 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700723 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800724
725 if (elidedReturn == nullptr && returnsValue) {
726 out << "using " << method->name() << "_cb = "
727 << iface->fqName().cppName()
728 << "::" << method->name() << "_cb;\n";
729 }
730 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800731 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800732 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800733
Steven Moreland19f11b52017-05-12 18:22:21 -0700734 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700735 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700736 out << "};\n\n";
737
738 enterLeaveNamespace(out, false /* enter */);
739
740 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700741}
742
Steven Moreland368e4602018-02-16 14:21:49 -0800743void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700744 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700745 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800746 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700747 }
748
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700749 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800750 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800751 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700752
753 out << "#ifndef " << guard << "\n";
754 out << "#define " << guard << "\n\n";
755
Martijn Coenen115d4282016-12-19 05:14:04 +0100756 out << "#include <hidl/HidlTransportSupport.h>\n\n";
757
Andreas Huber881227d2016-08-02 14:20:21 -0700758 std::vector<std::string> packageComponents;
759 getPackageAndVersionComponents(
760 &packageComponents, false /* cpp_compatible */);
761
Yifan Hongeefe4f22017-01-04 15:32:42 -0800762 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700763 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700764
765 enterLeaveNamespace(out, true /* enter */);
766 out << "\n";
767
768 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800769 << proxyName
770 << " : public ::android::hardware::BpInterface<"
771 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000772 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700773
774 out.indent();
775
Yifan Hongeefe4f22017-01-04 15:32:42 -0800776 out << "explicit "
777 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700778 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700779 << "\n\n";
780
Steven Moreland0b843772017-06-23 16:33:38 -0700781 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700782 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
783 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700784 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700785
Yifan Hong10fe0b52016-10-19 14:20:17 -0700786 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700787
Steven Moreland368e4602018-02-16 14:21:49 -0800788 generateMethods(
789 out,
790 [&](const Method* method, const Interface*) {
791 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
792 return;
793 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700794
Steven Moreland368e4602018-02-16 14:21:49 -0800795 out << "static ";
796 method->generateCppReturnType(out);
797 out << " _hidl_" << method->name() << "("
798 << "::android::hardware::IInterface* _hidl_this, "
799 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700800
Steven Moreland368e4602018-02-16 14:21:49 -0800801 if (!method->hasEmptyCppArgSignature()) {
802 out << ", ";
803 }
804 method->emitCppArgSignature(out);
805 out << ");\n";
806 },
807 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700808
Steven Moreland368e4602018-02-16 14:21:49 -0800809 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700810 method->generateCppSignature(out);
811 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700812 });
Steven Moreland9c387612016-09-07 09:54:26 -0700813
Andreas Huber881227d2016-08-02 14:20:21 -0700814 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100815 out << "private:\n";
816 out.indent();
817 out << "std::mutex _hidl_mMutex;\n"
818 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
819 << " _hidl_mDeathRecipients;\n";
820 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700821 out << "};\n\n";
822
823 enterLeaveNamespace(out, false /* enter */);
824
825 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700826}
827
Steven Moreland368e4602018-02-16 14:21:49 -0800828void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700829 std::string baseName = getBaseName();
830 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700831
Steven Morelanda885d252017-09-25 18:44:43 -0700832 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700833
Steven Moreland623c0042017-01-13 14:42:29 -0800834 out << "#define LOG_TAG \""
835 << mPackage.string() << "::" << baseName
836 << "\"\n\n";
837
Steven Moreland5add34d2018-11-08 16:31:30 -0800838 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100839 out << "#include <cutils/trace.h>\n";
840 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700841 out << "#include <hidl/Static.h>\n";
842 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700843 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700844 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700845 // This is a no-op for IServiceManager itself.
846 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
847
Yifan Hongeefe4f22017-01-04 15:32:42 -0800848 generateCppPackageInclude(out, mPackage, iface->getProxyName());
849 generateCppPackageInclude(out, mPackage, iface->getStubName());
850 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700851
852 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700853 generateCppPackageInclude(out,
854 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800855 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700856 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800857
858 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700859 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700860 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800861 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700862 }
863
864 out << "\n";
865
866 enterLeaveNamespace(out, true /* enter */);
867 out << "\n";
868
Steven Moreland368e4602018-02-16 14:21:49 -0800869 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700870
Steven Moreland368e4602018-02-16 14:21:49 -0800871 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700872 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700873
874 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800875 out << "const char* "
876 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700877 << "::descriptor(\""
878 << iface->fqName().string()
879 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800880 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100881 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800882 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800883 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800884 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800885 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800886 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800887 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800888 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800889 out << "return new "
890 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700891 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800892 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800893 << " *>(iIntf));\n";
894 });
Yifan Hongb04de382017-02-06 15:31:52 -0800895 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800896 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800897 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800898 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800899 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800900 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800901 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800902 << gIBaseFqName.cppName()
903 << "> {\n";
904 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800905 out << "return new "
906 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700907 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800908 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800909 << " *>(iIntf));\n";
910 });
Yifan Hongb04de382017-02-06 15:31:52 -0800911 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800912 });
Yifan Hong158655a2016-11-08 12:34:07 -0800913 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100914 out << "};\n\n";
915 out << "__attribute__((destructor))";
916 out << "static void static_destructor() {\n";
917 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800918 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100919 << iface->localName()
920 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800921 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100922 << iface->localName()
923 << "::descriptor);\n";
924 });
925 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800926
Steven Moreland368e4602018-02-16 14:21:49 -0800927 generateInterfaceSource(out);
928 generateProxySource(out, iface->fqName());
929 generateStubSource(out, iface);
930 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700931
Yifan Hongc8934042016-11-17 17:10:52 -0800932 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800933 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800934 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800935 std::string package = iface->fqName().package()
936 + iface->fqName().atVersion();
937
Yifan Hongeefe4f22017-01-04 15:32:42 -0800938 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800939 }
Steven Moreland40786312016-08-16 10:29:40 -0700940 }
941
Andreas Huber6755e9d2017-04-06 11:09:07 -0700942 HidlTypeAssertion::EmitAll(out);
943 out << "\n";
944
Andreas Huber881227d2016-08-02 14:20:21 -0700945 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700946}
947
Steven Moreland368e4602018-02-16 14:21:49 -0800948void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
949 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700950}
951
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700952void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
953 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700954 if (args.empty()) {
955 return;
956 }
957
958 for (const auto &arg : args) {
959 const Type &type = arg->type();
960
Yifan Hong3b320f82016-11-01 15:15:54 -0700961 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700962 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700963 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700964 << ";\n";
965 }
966
967 out << "\n";
968}
969
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700970void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
971 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
972 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700973 const Type &type = arg->type();
974
Andreas Huber881227d2016-08-02 14:20:21 -0700975 type.emitReaderWriter(
976 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700977 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700978 parcelObj,
979 parcelObjIsPointer,
980 isReader,
981 mode);
982}
983
Steven Moreland368e4602018-02-16 14:21:49 -0800984void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
985 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700986 method->generateCppSignature(out,
987 klassName,
988 true /* specify namespaces */);
989
Martijn Coenen115d4282016-12-19 05:14:04 +0100990 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -0700991 out.block([&] {
992 method->cppImpl(IMPL_PROXY, out);
993 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -0800994 return;
Martijn Coenen115d4282016-12-19 05:14:04 +0100995 }
996
Steven Morelandf16c5c02017-07-31 16:50:06 -0700997 out.block([&] {
998 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700999 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001000
1001 method->generateCppReturnType(out);
1002
1003 out << " _hidl_out = "
1004 << superInterface->fqName().cppNamespace()
1005 << "::"
1006 << superInterface->getProxyName()
1007 << "::_hidl_"
1008 << method->name()
1009 << "(this, this";
1010
1011 if (!method->hasEmptyCppArgSignature()) {
1012 out << ", ";
1013 }
1014
1015 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1016 out << arg->name();
1017 });
1018
1019 if (returnsValue && elidedReturn == nullptr) {
1020 if (!method->args().empty()) {
1021 out << ", ";
1022 }
1023 out << "_hidl_cb";
1024 }
1025
1026 out << ");\n\n";
1027
1028 out << "return _hidl_out;\n";
1029 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001030}
1031
Steven Moreland368e4602018-02-16 14:21:49 -08001032void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001033 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001034 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001035 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001036 }
1037
1038 method->generateCppReturnType(out);
1039
1040 out << klassName
1041 << "::_hidl_"
1042 << method->name()
1043 << "("
1044 << "::android::hardware::IInterface *_hidl_this, "
1045 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1046
1047 if (!method->hasEmptyCppArgSignature()) {
1048 out << ", ";
1049 }
1050
1051 method->emitCppArgSignature(out);
1052 out << ") {\n";
1053
1054 out.indent();
1055
1056 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1057 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1058 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1059 out << "#else\n";
1060 out << "(void) _hidl_this_instrumentor;\n";
1061 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1062
1063 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001064 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001065 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1066
Steven Moreland92a08a72017-07-31 14:57:37 -07001067 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001068 out,
1069 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001070 method,
1071 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001072
1073 out << "::android::hardware::Parcel _hidl_data;\n";
1074 out << "::android::hardware::Parcel _hidl_reply;\n";
1075 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001076 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001077 out << "::android::hardware::Status _hidl_status;\n\n";
1078
Steven Moreland48cc6042019-04-30 11:28:56 -07001079 if (!hasCallback) {
1080 declareCppReaderLocals(
1081 out, method->results(), true /* forResults */);
1082 }
Yifan Hong068c5522016-10-31 14:07:25 -07001083
1084 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001085 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001086 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001087 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1088
Martijn Coenenfff73352017-01-04 16:36:31 +01001089 bool hasInterfaceArgument = false;
Steven Moreland8249f0a2019-05-28 17:25:27 -07001090
Yifan Hong068c5522016-10-31 14:07:25 -07001091 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001092 if (arg->type().isInterface()) {
1093 hasInterfaceArgument = true;
1094 }
Yifan Hong068c5522016-10-31 14:07:25 -07001095 emitCppReaderWriter(
1096 out,
1097 "_hidl_data",
1098 false /* parcelObjIsPointer */,
1099 arg,
1100 false /* reader */,
1101 Type::ErrorMode_Goto,
1102 false /* addPrefixToName */);
1103 }
1104
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001105 if (hasInterfaceArgument) {
1106 // Start binder threadpool to handle incoming transactions
1107 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1108 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001109 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001110 << method->getSerialId()
1111 << " /* "
1112 << method->name()
1113 << " */, _hidl_data, &_hidl_reply";
1114
1115 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001116 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001117 } else {
1118 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001119 }
Yifan Hong068c5522016-10-31 14:07:25 -07001120
Steven Moreland48cc6042019-04-30 11:28:56 -07001121 if (hasCallback) {
1122 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1123 out.indent();
1124 declareCppReaderLocals(
1125 out, method->results(), true /* forResults */);
1126 out.endl();
1127 } else {
1128 out << ");\n";
1129 out << "if (_hidl_transact_err != ::android::OK) \n";
1130 out.block([&] {
1131 out << "_hidl_err = _hidl_transact_err;\n";
1132 out << "goto _hidl_error;\n";
1133 }).endl().endl();
1134 }
Yifan Hong068c5522016-10-31 14:07:25 -07001135
1136 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001137 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001138
Steven Moreland48cc6042019-04-30 11:28:56 -07001139 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1140 Type::handleError(out, errorMode);
1141
1142 if (hasCallback) {
1143 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1144 } else {
1145 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1146 }
Yifan Hong068c5522016-10-31 14:07:25 -07001147
Yifan Hong068c5522016-10-31 14:07:25 -07001148 for (const auto &arg : method->results()) {
1149 emitCppReaderWriter(
1150 out,
1151 "_hidl_reply",
1152 false /* parcelObjIsPointer */,
1153 arg,
1154 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001155 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001156 true /* addPrefixToName */);
1157 }
1158
Yifan Hong068c5522016-10-31 14:07:25 -07001159 if (returnsValue && elidedReturn == nullptr) {
1160 out << "_hidl_cb(";
1161
Yifan Hong932464e2017-03-30 15:40:22 -07001162 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001163 if (arg->type().resultNeedsDeref()) {
1164 out << "*";
1165 }
1166 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001167 });
Yifan Hong068c5522016-10-31 14:07:25 -07001168
1169 out << ");\n\n";
1170 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001171 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001172
Steven Moreland92a08a72017-07-31 14:57:37 -07001173 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001174 out,
1175 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001176 method,
1177 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001178
Steven Moreland48cc6042019-04-30 11:28:56 -07001179 if (hasCallback) {
1180 out.unindent();
1181 out << "});\n";
1182 out << "if (_hidl_transact_err != ::android::OK) ";
1183 out.block([&] {
1184 out << "_hidl_err = _hidl_transact_err;\n";
1185 out << "goto _hidl_error;\n";
1186 }).endl().endl();
1187 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1188 }
1189
Yifan Hong068c5522016-10-31 14:07:25 -07001190 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001191 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001192 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001193 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1194 } else {
Yifan Hong068c5522016-10-31 14:07:25 -07001195 out << "return ::android::hardware::Return<void>();\n\n";
1196 }
1197
1198 out.unindent();
1199 out << "_hidl_error:\n";
1200 out.indent();
1201 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1202 out << "return ::android::hardware::Return<";
1203 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001204 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001205 } else {
1206 out << "void";
1207 }
1208 out << ">(_hidl_status);\n";
1209
1210 out.unindent();
1211 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001212}
1213
Steven Moreland368e4602018-02-16 14:21:49 -08001214void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001215 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001216
1217 out << klassName
1218 << "::"
1219 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001220 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001221
1222 out.indent();
1223 out.indent();
1224
1225 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001226 << "<"
1227 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001228 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001229 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001230 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001231 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001232 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001233 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001234
Andreas Huber881227d2016-08-02 14:20:21 -07001235 out.unindent();
1236 out.unindent();
1237 out << "}\n\n";
1238
Steven Moreland368e4602018-02-16 14:21:49 -08001239 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001240 [&](const Method* method, const Interface* superInterface) {
1241 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001242 },
1243 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001244
Steven Moreland368e4602018-02-16 14:21:49 -08001245 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1246 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001247 });
Andreas Huber881227d2016-08-02 14:20:21 -07001248}
1249
Steven Moreland368e4602018-02-16 14:21:49 -08001250void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001251 const std::string interfaceName = iface->localName();
1252 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001253
Steven Moreland40786312016-08-16 10:29:40 -07001254 out << klassName
1255 << "::"
1256 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001257 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001258
1259 out.indent();
1260 out.indent();
1261
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001262 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001263 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001264 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001265 out << ": "
1266 << gIBaseFqName.getInterfaceStubFqName().cppName()
1267 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001268 }
1269
1270 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001271 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001272 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001273 << "\") { \n";
1274 out.indent();
1275 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001276 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001277 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1278 out << "mSchedPolicy = prio.sched_policy;\n";
1279 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001280 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1281 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001282 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001283
1284 out.unindent();
1285 out.unindent();
1286 out << "}\n\n";
1287
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001288 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001289 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001290 // class properly.
1291 out << klassName
1292 << "::"
1293 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001294 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1295 << " const std::string &HidlInstrumentor_package,"
1296 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001297
1298 out.indent();
1299 out.indent();
1300
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001301 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001302 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001303 out.indent();
1304 out << "_hidl_mImpl = _hidl_impl;\n";
1305 out.unindent();
1306
1307 out.unindent();
1308 out.unindent();
1309 out << "}\n\n";
1310 }
1311
Steven Moreland57a89362017-07-21 19:29:54 +00001312 out << klassName << "::~" << klassName << "() ";
1313 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001314 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1315 })
1316 .endl()
1317 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001318
Steven Moreland368e4602018-02-16 14:21:49 -08001319 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001320 [&](const Method* method, const Interface* superInterface) {
1321 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001322 },
1323 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001324
Steven Moreland368e4602018-02-16 14:21:49 -08001325 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001326 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001327 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001328 }
1329 method->generateCppSignature(out, iface->getStubName());
1330 out << " ";
1331 out.block([&] {
1332 method->cppImpl(IMPL_STUB_IMPL, out);
1333 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001334 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001335
Andreas Huber881227d2016-08-02 14:20:21 -07001336 out << "::android::status_t " << klassName << "::onTransact(\n";
1337
1338 out.indent();
1339 out.indent();
1340
Iliyan Malchev549e2592016-08-10 08:59:12 -07001341 out << "uint32_t _hidl_code,\n"
1342 << "const ::android::hardware::Parcel &_hidl_data,\n"
1343 << "::android::hardware::Parcel *_hidl_reply,\n"
1344 << "uint32_t _hidl_flags,\n"
1345 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001346
1347 out.unindent();
1348
Iliyan Malchev549e2592016-08-10 08:59:12 -07001349 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001350 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001351 out.indent();
1352
Yifan Hong10fe0b52016-10-19 14:20:17 -07001353 for (const auto &tuple : iface->allMethodsFromRoot()) {
1354 const Method *method = tuple.method();
1355 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001356
Howard Chen71f289f2017-08-29 17:35:01 +08001357 if (!isIBase() && method->isHidlReserved()) {
1358 continue;
1359 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001360 out << "case "
1361 << method->getSerialId()
1362 << " /* "
1363 << method->name()
1364 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001365
Yifan Hong10fe0b52016-10-19 14:20:17 -07001366 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001367
Steven Moreland368e4602018-02-16 14:21:49 -08001368 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001369
1370 out.unindent();
1371 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001372 }
1373
1374 out << "default:\n{\n";
1375 out.indent();
1376
Martijn Coenen225bc922017-06-27 14:39:46 -07001377 if (iface->isIBase()) {
1378 out << "(void)_hidl_flags;\n";
1379 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1380 } else {
1381 out << "return ";
1382 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1383 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001384
Martijn Coenen225bc922017-06-27 14:39:46 -07001385 out.indent();
1386 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001387
Martijn Coenen225bc922017-06-27 14:39:46 -07001388 out << "_hidl_code, _hidl_data, _hidl_reply, "
1389 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001390
Martijn Coenen225bc922017-06-27 14:39:46 -07001391 out.unindent();
1392 out.unindent();
1393 }
Andreas Huber881227d2016-08-02 14:20:21 -07001394
1395 out.unindent();
1396 out << "}\n";
1397
1398 out.unindent();
1399 out << "}\n\n";
1400
Yifan Honga018ed52016-12-13 16:35:08 -08001401 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1402 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1403 out.indent(2, [&] {
1404 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1405 out << "_hidl_reply);\n";
1406 });
1407 });
Andreas Huber881227d2016-08-02 14:20:21 -07001408
Iliyan Malchev549e2592016-08-10 08:59:12 -07001409 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001410
1411 out.unindent();
1412 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001413}
1414
Steven Moreland368e4602018-02-16 14:21:49 -08001415void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1416 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001417 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1418 method->cppImpl(IMPL_STUB, out);
1419 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001420 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001421 }
1422
Steven Morelandf16c5c02017-07-31 16:50:06 -07001423 out << "_hidl_err = "
1424 << superInterface->fqName().cppNamespace()
1425 << "::"
1426 << superInterface->getStubName()
1427 << "::_hidl_"
1428 << method->name()
1429 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1430 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001431}
1432
Steven Moreland368e4602018-02-16 14:21:49 -08001433void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001434 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001435 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001436 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001437 }
1438
Steven Morelandf8197902018-01-30 15:38:37 -08001439 const std::string& klassName = fqName.getInterfaceStubName();
1440
Steven Morelandf16c5c02017-07-31 16:50:06 -07001441 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1442
1443 out.indent();
1444 out.indent();
1445
1446 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1447 << "const ::android::hardware::Parcel &_hidl_data,\n"
1448 << "::android::hardware::Parcel *_hidl_reply,\n"
1449 << "TransactCallback _hidl_cb) {\n";
1450
1451 out.unindent();
1452
1453 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1454 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1455 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1456 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1457
1458 out << "::android::status_t _hidl_err = ::android::OK;\n";
1459
Yifan Hongeefe4f22017-01-04 15:32:42 -08001460 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001461 << klassName
1462 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001463
Andreas Huber881227d2016-08-02 14:20:21 -07001464 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001465 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001466 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001467 out.unindent();
1468 out << "}\n\n";
1469
Andreas Huber5e44a292016-09-27 14:52:39 -07001470 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001471
Andreas Huber881227d2016-08-02 14:20:21 -07001472 for (const auto &arg : method->args()) {
1473 emitCppReaderWriter(
1474 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001475 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001476 false /* parcelObjIsPointer */,
1477 arg,
1478 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001479 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001480 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001481 }
1482
Steven Moreland92a08a72017-07-31 14:57:37 -07001483 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001484 out,
1485 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001486 method,
1487 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001488
Andreas Huber881227d2016-08-02 14:20:21 -07001489 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001490 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001491
1492 std::string callee;
1493
1494 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1495 callee = "_hidl_this";
1496 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001497 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001498 }
Andreas Huber881227d2016-08-02 14:20:21 -07001499
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001500 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001501 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001502 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001503 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001504 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001505 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001506 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001507
Yifan Hong932464e2017-03-30 15:40:22 -07001508 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001509 if (arg->type().resultNeedsDeref()) {
1510 out << "*";
1511 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001512 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001513 });
Andreas Huber881227d2016-08-02 14:20:21 -07001514
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001515 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001516
Yifan Hong859e53f2016-11-14 19:08:24 -08001517 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1518 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001519
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001520 elidedReturn->type().emitReaderWriter(
1521 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001522 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001523 "_hidl_reply",
1524 true, /* parcelObjIsPointer */
1525 false, /* isReader */
1526 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001527
Steven Moreland92a08a72017-07-31 14:57:37 -07001528 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001529 out,
1530 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001531 method,
1532 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001533
Iliyan Malchev549e2592016-08-10 08:59:12 -07001534 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001535 } else {
1536 if (returnsValue) {
1537 out << "bool _hidl_callbackCalled = false;\n\n";
1538 }
Andreas Huber881227d2016-08-02 14:20:21 -07001539
Steven Moreland30232dc2019-03-05 19:39:10 -08001540 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1541 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001542
Yifan Hong932464e2017-03-30 15:40:22 -07001543 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001544 if (arg->type().resultNeedsDeref()) {
1545 out << "*";
1546 }
1547
1548 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001549 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001550
1551 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001552 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001553 out << ", ";
1554 }
1555
1556 out << "[&](";
1557
Yifan Hong932464e2017-03-30 15:40:22 -07001558 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001559 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001560 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001561
1562 out << ") {\n";
1563 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001564 out << "if (_hidl_callbackCalled) {\n";
1565 out.indent();
1566 out << "LOG_ALWAYS_FATAL(\""
1567 << method->name()
1568 << ": _hidl_cb called a second time, but must be called once.\");\n";
1569 out.unindent();
1570 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001571 out << "_hidl_callbackCalled = true;\n\n";
1572
Yifan Hong859e53f2016-11-14 19:08:24 -08001573 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1574 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001575
1576 for (const auto &arg : method->results()) {
1577 emitCppReaderWriter(
1578 out,
1579 "_hidl_reply",
1580 true /* parcelObjIsPointer */,
1581 arg,
1582 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001583 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001584 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001585 }
1586
Steven Moreland92a08a72017-07-31 14:57:37 -07001587 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001588 out,
1589 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001590 method,
1591 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001592
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001593 out << "_hidl_cb(*_hidl_reply);\n";
1594
1595 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001596 out << "});\n\n";
1597 } else {
1598 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001599 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001600 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001601 out,
1602 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001603 method,
1604 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001605 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001606
Steven Moreland30232dc2019-03-05 19:39:10 -08001607 out << "_hidl_ret.assertOk();\n";
1608
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001609 if (returnsValue) {
1610 out << "if (!_hidl_callbackCalled) {\n";
1611 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001612 out << "LOG_ALWAYS_FATAL(\""
1613 << method->name()
1614 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001615 out.unindent();
1616 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001617 } else {
1618 out << "::android::hardware::writeToParcel("
1619 << "::android::hardware::Status::ok(), "
1620 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001621 }
Andreas Huber881227d2016-08-02 14:20:21 -07001622 }
1623
Steven Morelandf16c5c02017-07-31 16:50:06 -07001624 out << "return _hidl_err;\n";
1625 out.unindent();
1626 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001627}
1628
Steven Moreland368e4602018-02-16 14:21:49 -08001629void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001630 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001631 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001632 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001633 }
1634
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001635 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001636 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001637
Yifan Hongeefe4f22017-01-04 15:32:42 -08001638 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001639
Steven Moreland69e7c702016-09-09 11:16:32 -07001640 const std::string guard = makeHeaderGuard(klassName);
1641
1642 out << "#ifndef " << guard << "\n";
1643 out << "#define " << guard << "\n\n";
1644
1645 std::vector<std::string> packageComponents;
1646 getPackageAndVersionComponents(
1647 &packageComponents, false /* cpp_compatible */);
1648
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001649 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001650 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001651 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001652
Steven Moreland19f11b52017-05-12 18:22:21 -07001653 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001654 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001655
Yifan Hong7a118f52016-12-07 11:21:15 -08001656 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001657 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001658
1659 enterLeaveNamespace(out, true /* enter */);
1660 out << "\n";
1661
1662 out << "struct "
1663 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001664 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001665 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001666
1667 out.indent();
1668 out << "explicit "
1669 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001670 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001671 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001672 << "> impl);\n";
1673
Steven Moreland0b843772017-06-23 16:33:38 -07001674 out.endl();
1675 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001676 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001677
Steven Moreland616cf4d2018-10-02 13:52:18 -07001678 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1679 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001680 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001681
Steven Moreland69e7c702016-09-09 11:16:32 -07001682 out.unindent();
1683 out << "private:\n";
1684 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001685 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001686
Neel Mehta19f79792019-05-21 13:39:32 -07001687 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001688
Neel Mehta19f79792019-05-21 13:39:32 -07001689 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001690
Neel Mehta19f79792019-05-21 13:39:32 -07001691 out << "::android::hardware::Return<void> addOnewayTask("
1692 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001693
1694 out.unindent();
1695
1696 out << "};\n\n";
1697
1698 enterLeaveNamespace(out, false /* enter */);
1699
1700 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001701}
1702
Steven Moreland368e4602018-02-16 14:21:49 -08001703void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001704 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001705
Yifan Hong2d7126b2016-10-20 15:12:57 -07001706 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001707 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001708
Steven Moreland368e4602018-02-16 14:21:49 -08001709 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001710 bool reserved = method->isHidlReserved();
1711
1712 if (!reserved) {
1713 out << "// no default implementation for: ";
1714 }
1715 method->generateCppSignature(out, iface->localName());
1716 if (reserved) {
1717 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001718 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001719 }).endl();
1720 }
1721
1722 out << "\n";
1723
Steven Moreland368e4602018-02-16 14:21:49 -08001724 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001725 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001726
Yifan Hong3d746092016-12-07 14:26:33 -08001727 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001728 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001729 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001730 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001731 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001732 << "::castFrom("
1733 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001734 << " parent, bool "
1735 << (iface == superType ? "/* emitError */" : "emitError")
1736 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001737 out.indent();
1738 if (iface == superType) {
1739 out << "return parent;\n";
1740 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001741 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001742 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001743 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001744 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001745 << ">(\n";
1746 out.indent();
1747 out.indent();
1748 out << "parent, \""
1749 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001750 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001751 out.unindent();
1752 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001753 }
Yifan Hong3d746092016-12-07 14:26:33 -08001754 out.unindent();
1755 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001756 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001757}
1758
Steven Moreland368e4602018-02-16 14:21:49 -08001759void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001760 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001761
Yifan Hongeefe4f22017-01-04 15:32:42 -08001762 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001763
Neel Mehta19f79792019-05-21 13:39:32 -07001764 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1765 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1766 << "\", \"" << iface->localName() << "\"), mImpl(impl) {\n";
1767
1768 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1769
Yifan Hong2cbc1472016-10-25 19:02:40 -07001770 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001771
Neel Mehta19f79792019-05-21 13:39:32 -07001772 out << "::android::hardware::Return<void> " << klassName
1773 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1774 out.indent();
1775 out << "if (!mOnewayQueue.push(fun)) {\n";
1776 out.indent();
1777 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1778 out.indent();
1779 out.indent();
1780 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1781 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1782 out.unindent();
1783 out.unindent();
1784 out.unindent();
1785 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001786
Neel Mehta19f79792019-05-21 13:39:32 -07001787 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001788
Neel Mehta19f79792019-05-21 13:39:32 -07001789 out.unindent();
1790 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001791}
1792
Steven Moreland92a08a72017-07-31 14:57:37 -07001793void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001794 InstrumentationEvent event,
1795 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001796 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001797 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001798 switch (event) {
1799 case SERVER_API_ENTRY:
1800 {
1801 out << "atrace_begin(ATRACE_TAG_HAL, \""
1802 << baseString + "::server\");\n";
1803 break;
1804 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001805 case PASSTHROUGH_ENTRY:
1806 {
1807 out << "atrace_begin(ATRACE_TAG_HAL, \""
1808 << baseString + "::passthrough\");\n";
1809 break;
1810 }
1811 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001812 case PASSTHROUGH_EXIT:
1813 {
1814 out << "atrace_end(ATRACE_TAG_HAL);\n";
1815 break;
1816 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001817 // client uses scope because of gotos
1818 // this isn't done for server because the profiled code isn't alone in its scope
1819 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1820 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001821 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1822 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001823 break;
1824 }
1825 case CLIENT_API_EXIT:
1826 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001827 default:
1828 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001829 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001830 }
1831 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001832}
1833
Steven Moreland92a08a72017-07-31 14:57:37 -07001834void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001835 Formatter &out,
1836 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001837 const Method *method,
1838 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001839 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001840
Steven Moreland30b76e92017-06-02 18:52:24 -07001841 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001842 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1843 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001844 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001845 std::string event_str = "";
1846 switch (event) {
1847 case SERVER_API_ENTRY:
1848 {
1849 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1850 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001851 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001852 << (arg->type().resultNeedsDeref() ? "" : "&")
1853 << arg->name()
1854 << ");\n";
1855 }
1856 break;
1857 }
1858 case SERVER_API_EXIT:
1859 {
1860 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001861 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001862 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001863 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001864 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001865 }
1866 break;
1867 }
1868 case CLIENT_API_ENTRY:
1869 {
1870 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1871 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001872 out << "_hidl_args.push_back((void *)&"
1873 << arg->name()
1874 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001875 }
1876 break;
1877 }
1878 case CLIENT_API_EXIT:
1879 {
1880 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1881 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001882 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001883 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001884 << "_hidl_out_"
1885 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001886 << ");\n";
1887 }
1888 break;
1889 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001890 case PASSTHROUGH_ENTRY:
1891 {
1892 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1893 for (const auto &arg : method->args()) {
1894 out << "_hidl_args.push_back((void *)&"
1895 << arg->name()
1896 << ");\n";
1897 }
1898 break;
1899 }
1900 case PASSTHROUGH_EXIT:
1901 {
1902 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001903 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001904 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001905 << arg->name()
1906 << ");\n";
1907 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001908 break;
1909 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001910 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001911 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001912 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001913 }
1914 }
1915
Steven Moreland1ab31442016-11-03 18:37:51 -07001916 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001917 out.indent();
1918 out << "callback("
1919 << event_str
1920 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001921 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001922 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001923 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001924 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001925 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001926 << "\", \""
1927 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001928 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001929 out.unindent();
1930 out << "}\n";
1931 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001932 out << "}\n";
1933 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001934}
1935
Andreas Huber881227d2016-08-02 14:20:21 -07001936} // namespace android