blob: 72c8e827d6a85f54781d0cf653adea3b10a43bf9 [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"
Neel Mehta291d02e2019-06-06 17:51:07 -070023#include "Location.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070025#include "Reference.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070026#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070027#include "Scope.h"
28
Andreas Huberdca261f2016-08-04 13:47:51 -070029#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070030#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000031#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070032#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070033#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070034#include <vector>
35
36namespace android {
37
Steven Moreland5708edf2016-11-04 15:33:31 +000038std::string AST::makeHeaderGuard(const std::string &baseName,
39 bool indicateGenerated) const {
40 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070041
Steven Moreland5708edf2016-11-04 15:33:31 +000042 if (indicateGenerated) {
43 guard += "HIDL_GENERATED_";
44 }
45
46 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070047 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000048 guard += StringHelper::Uppercase(baseName);
49 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070050
51 return guard;
52}
53
Steven Morelandee88eed2016-10-31 17:49:00 -070054void AST::generateCppPackageInclude(
55 Formatter &out,
56 const FQName &package,
57 const std::string &klass) {
58
59 out << "#include <";
60
Steven Moreland4a385ed2019-12-09 14:47:18 -080061 std::vector<std::string> components =
62 package.getPackageAndVersionComponents(false /* sanitized */);
Steven Morelandee88eed2016-10-31 17:49:00 -070063
64 for (const auto &component : components) {
65 out << component << "/";
66 }
67
68 out << klass
69 << ".h>\n";
70}
71
Andreas Huber881227d2016-08-02 14:20:21 -070072void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
Steven Moreland4a385ed2019-12-09 14:47:18 -080073 std::vector<std::string> packageComponents =
74 mPackage.getPackageAndVersionComponents(true /* sanitized */);
Andreas Huber881227d2016-08-02 14:20:21 -070075
76 if (enter) {
77 for (const auto &component : packageComponents) {
78 out << "namespace " << component << " {\n";
79 }
80 } else {
81 for (auto it = packageComponents.rbegin();
82 it != packageComponents.rend();
83 ++it) {
84 out << "} // namespace " << *it << "\n";
85 }
86 }
87}
88
Steven Moreland038903b2017-03-30 12:11:24 -070089static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
90 const std::string functionName = isTry ? "tryGetService" : "getService";
91
Steven Moreland7645fbd2019-03-12 18:49:28 -070092 if (isTry) {
93 DocComment(
94 "This gets the service of this type with the specified instance name. If the\n"
95 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
96 "device, this will return nullptr. This is useful when you don't want to block\n"
97 "during device boot. If getStub is true, this will try to return an unwrapped\n"
98 "passthrough implementation in the same process. This is useful when getting an\n"
99 "implementation from the same partition/compilation group.\n\n"
Neel Mehta291d02e2019-06-06 17:51:07 -0700100 "In general, prefer getService(std::string,bool)",
101 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700102 .emit(out);
103 } else {
104 DocComment(
105 "This gets the service of this type with the specified instance name. If the\n"
106 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
107 "nullptr. If the service is not available, this will wait for the service to\n"
108 "become available. If the service is a lazy service, this will start the service\n"
109 "and return when it becomes available. If getStub is true, this will try to\n"
110 "return an unwrapped passthrough implementation in the same process. This is\n"
Neel Mehta291d02e2019-06-06 17:51:07 -0700111 "useful when getting an implementation from the same partition/compilation group.",
112 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700113 .emit(out);
114 }
Steven Moreland038903b2017-03-30 12:11:24 -0700115 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800116 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Neel Mehta291d02e2019-06-06 17:51:07 -0700117 DocComment("Deprecated. See " + functionName + "(std::string, bool)", HIDL_LOCATION_HERE)
118 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700119 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800120 << "const char serviceName[], bool getStub=false)"
121 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700122 << " return " << functionName << "(str, getStub); }\n";
Neel Mehta291d02e2019-06-06 17:51:07 -0700123 DocComment("Deprecated. See " + functionName + "(std::string, bool)", HIDL_LOCATION_HERE)
124 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700125 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800126 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
127 // without c_str the std::string constructor is ambiguous
128 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700129 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700130 DocComment("Calls " + functionName +
Neel Mehta291d02e2019-06-06 17:51:07 -0700131 "(\"default\", bool). This is the recommended instance name for singleton "
132 "services.",
133 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700134 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700135 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
136 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
137}
138
139static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
140 declareGetService(out, interfaceName, true /* isTry */);
141 declareGetService(out, interfaceName, false /* isTry */);
142
Steven Moreland7645fbd2019-03-12 18:49:28 -0700143 DocComment(
144 "Registers a service with the service manager. For Trebilized devices, the service\n"
Neel Mehta291d02e2019-06-06 17:51:07 -0700145 "must also be in the VINTF manifest.",
146 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700147 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700148 out << "__attribute__ ((warn_unused_result))"
149 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Neel Mehta291d02e2019-06-06 17:51:07 -0700150 DocComment("Registers for notifications for when a service is registered.", HIDL_LOCATION_HERE)
151 .emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800152 out << "static bool registerForNotifications(\n";
153 out.indent(2, [&] {
154 out << "const std::string &serviceName,\n"
155 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
156 << "&notification);\n";
157 });
158
159}
160
Steven Moreland038903b2017-03-30 12:11:24 -0700161static void implementGetService(Formatter &out,
162 const FQName &fqName,
163 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800164
165 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700166 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800167
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700168 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000169 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800170 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700171 out << "return ::android::hardware::details::getServiceInternal<"
172 << fqName.getInterfaceProxyName()
173 << ">(serviceName, "
174 << (!isTry ? "true" : "false") // retry
175 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800176 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700177}
178
179static void implementServiceManagerInteractions(Formatter &out,
180 const FQName &fqName, const std::string &package) {
181
182 const std::string interfaceName = fqName.getInterfaceName();
183
184 implementGetService(out, fqName, true /* isTry */);
185 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800186
Yifan Hongeefe4f22017-01-04 15:32:42 -0800187 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800188 << "const std::string &serviceName) ";
189 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700190 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800191 }).endl().endl();
192
Yifan Hongeefe4f22017-01-04 15:32:42 -0800193 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800194 out.indent(2, [&] {
195 out << "const std::string &serviceName,\n"
196 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
197 << "&notification) ";
198 });
199 out.block([&] {
200 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
201 out.indent(2, [&] {
202 out << "= ::android::hardware::defaultServiceManager();\n";
203 });
204 out.sIf("sm == nullptr", [&] {
205 out << "return false;\n";
206 }).endl();
207 out << "::android::hardware::Return<bool> success =\n";
208 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800209 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800210 out.indent(2, [&] {
211 out << "serviceName, notification);\n";
212 });
213 });
214 out << "return success.isOk() && success;\n";
215 }).endl().endl();
216}
217
Steven Moreland368e4602018-02-16 14:21:49 -0800218void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700219 const Interface *iface = getInterface();
Neel Mehta9200af02019-07-19 13:24:57 -0700220 std::string ifaceName = iface ? iface->definedName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700221 const std::string guard = makeHeaderGuard(ifaceName);
222
223 out << "#ifndef " << guard << "\n";
224 out << "#define " << guard << "\n\n";
225
Andreas Huber737080b2016-08-02 15:38:04 -0700226 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700227 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700228 }
229
230 if (!mImportedNames.empty()) {
231 out << "\n";
232 }
233
Steven Moreland19f11b52017-05-12 18:22:21 -0700234 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800235 if (isIBase()) {
236 out << "// skipped #include IServiceNotification.h\n\n";
237 } else {
238 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
239 }
Steven Moreland0693f312016-11-09 15:06:14 -0800240 }
241
Yifan Hongc8934042016-11-17 17:10:52 -0800242 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700243 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700244
Steven Moreland19f11b52017-05-12 18:22:21 -0700245 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200246 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700247 }
248
Martijn Coenenaf712c02016-11-16 15:26:27 +0100249 out << "#include <utils/NativeHandle.h>\n";
250 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700251
252 enterLeaveNamespace(out, true /* enter */);
253 out << "\n";
254
Steven Moreland19f11b52017-05-12 18:22:21 -0700255 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700256 iface->emitDocComment(out);
257
Andreas Huber881227d2016-08-02 14:20:21 -0700258 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700259 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700260
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700261 const Interface *superType = iface->superType();
262
Yi Kong56758da2018-07-24 16:21:37 -0700263 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800264 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700265 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000266 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700267 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700268 }
269
270 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700271
272 out.indent();
273
Neel Mehta291d02e2019-06-06 17:51:07 -0700274 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.",
275 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700276 .emit(out);
Diogo Ferreira604fe012019-10-17 12:32:00 +0100277 generateCppTag(out, "::android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700278
Neel Mehta291d02e2019-06-06 17:51:07 -0700279 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"",
280 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700281 .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(
Neel Mehta291d02e2019-06-06 17:51:07 -0700291 "Returns whether this object's implementation is outside of the current process.",
292 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700293 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800294 out << "virtual bool isRemote() const ";
295 if (!isIBase()) {
296 out << "override ";
297 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700298 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800299
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700300 for (const auto& tuple : iface->allMethodsFromRoot()) {
301 const Method* method = tuple.method();
302
Andreas Huber881227d2016-08-02 14:20:21 -0700303 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700304
Andreas Huber881227d2016-08-02 14:20:21 -0700305 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700306 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800307
308 if (elidedReturn == nullptr && returnsValue) {
Neel Mehta291d02e2019-06-06 17:51:07 -0700309 DocComment("Return callback for " + method->name(), HIDL_LOCATION_HERE).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800310 out << "using "
311 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700312 << "_cb = std::function<void(";
313 method->emitCppResultSignature(out, true /* specify namespaces */);
314 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800315 }
Andreas Huber881227d2016-08-02 14:20:21 -0700316
Steven Moreland49bad8d2018-05-17 15:45:26 -0700317 method->emitDocComment(out);
318
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700319 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700320 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700321 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700322 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700323 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700324 }
325
326 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700327 << "(";
328 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700329 out << ")";
330 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800331 if (!isIBase()) {
332 out << " override";
333 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700334 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700335 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700336 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700337 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700338 }
Steven Moreland40786312016-08-16 10:29:40 -0700339
Steven Moreland7645fbd2019-03-12 18:49:28 -0700340 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800341 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700342
Yifan Hong3d746092016-12-07 14:26:33 -0800343 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700344 DocComment(
345 "This performs a checked cast based on what the underlying implementation "
Neel Mehta291d02e2019-06-06 17:51:07 -0700346 "actually is.",
347 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700348 .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";
Neel Mehta9200af02019-07-19 13:24:57 -0700361 declareServiceManagerInteractions(out, iface->definedName());
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
Neel Mehta9200af02019-07-19 13:24:57 -0700401 generateCppPackageInclude(out, mPackage, iface ? iface->definedName() : "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 {
Neel Mehta291d02e2019-06-06 17:51:07 -0700627 DocComment("The pure class is what this class wraps.", HIDL_LOCATION_HERE).emit(out);
Neel Mehta9200af02019-07-19 13:24:57 -0700628 out << "typedef " << mRootScope.getInterface()->definedName() << " 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();
Neel Mehta9200af02019-07-19 13:24:57 -0700664 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
665 << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100666 << "\n";
Neel Mehta9200af02019-07-19 13:24:57 -0700667 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
668 << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800669 << " const std::string& HidlInstrumentor_package,"
670 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700671 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000672 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700673 out << "::android::status_t onTransact(\n";
674 out.indent();
675 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700676 out << "uint32_t _hidl_code,\n";
677 out << "const ::android::hardware::Parcel &_hidl_data,\n";
678 out << "::android::hardware::Parcel *_hidl_reply,\n";
679 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700680 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700681 out.unindent();
682 out.unindent();
683
Steven Moreland0b843772017-06-23 16:33:38 -0700684 out.endl();
685 generateTemplatizationLink(out);
Neel Mehta291d02e2019-06-06 17:51:07 -0700686 DocComment("Type tag for use in template logic that indicates this is a 'native' class.",
687 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700688 .emit(out);
Diogo Ferreira604fe012019-10-17 12:32:00 +0100689 generateCppTag(out, "::android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700690
Neel Mehta9200af02019-07-19 13:24:57 -0700691 out << "::android::sp<" << iface->definedName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700692
Steven Moreland368e4602018-02-16 14:21:49 -0800693 generateMethods(out,
694 [&](const Method* method, const Interface*) {
695 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
696 return;
697 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700698
Steven Moreland368e4602018-02-16 14:21:49 -0800699 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700700
Steven Moreland368e4602018-02-16 14:21:49 -0800701 out.indent(2,
702 [&] {
703 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
704 << "const ::android::hardware::Parcel &_hidl_data,\n"
705 << "::android::hardware::Parcel *_hidl_reply,\n"
706 << "TransactCallback _hidl_cb);\n";
707 })
708 .endl()
709 .endl();
710 },
711 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700712
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100713 out.unindent();
714 out << "private:\n";
715 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800716
Steven Moreland368e4602018-02-16 14:21:49 -0800717 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800718 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800719 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800720 }
721 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700722 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800723
724 if (elidedReturn == nullptr && returnsValue) {
725 out << "using " << method->name() << "_cb = "
726 << iface->fqName().cppName()
727 << "::" << method->name() << "_cb;\n";
728 }
729 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800730 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800731 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800732
Neel Mehta9200af02019-07-19 13:24:57 -0700733 out << "::android::sp<" << iface->definedName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700734 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700735 out << "};\n\n";
736
737 enterLeaveNamespace(out, false /* enter */);
738
739 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700740}
741
Steven Moreland368e4602018-02-16 14:21:49 -0800742void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700743 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700744 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800745 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700746 }
747
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700748 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800749 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800750 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700751
752 out << "#ifndef " << guard << "\n";
753 out << "#define " << guard << "\n\n";
754
Martijn Coenen115d4282016-12-19 05:14:04 +0100755 out << "#include <hidl/HidlTransportSupport.h>\n\n";
756
Yifan Hongeefe4f22017-01-04 15:32:42 -0800757 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700758 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700759
760 enterLeaveNamespace(out, true /* enter */);
761 out << "\n";
762
Neel Mehta9200af02019-07-19 13:24:57 -0700763 out << "struct " << proxyName << " : public ::android::hardware::BpInterface<"
764 << iface->definedName() << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700765
766 out.indent();
767
Yifan Hongeefe4f22017-01-04 15:32:42 -0800768 out << "explicit "
769 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700770 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700771 << "\n\n";
772
Steven Moreland0b843772017-06-23 16:33:38 -0700773 generateTemplatizationLink(out);
Neel Mehta291d02e2019-06-06 17:51:07 -0700774 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.",
775 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700776 .emit(out);
Diogo Ferreira604fe012019-10-17 12:32:00 +0100777 generateCppTag(out, "::android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700778
Yifan Hong10fe0b52016-10-19 14:20:17 -0700779 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700780
Steven Moreland596d20e2019-06-07 11:52:21 -0700781 out << "void onLastStrongRef(const void* id) override;\n\n";
782
Steven Moreland368e4602018-02-16 14:21:49 -0800783 generateMethods(
784 out,
785 [&](const Method* method, const Interface*) {
786 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
787 return;
788 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700789
Steven Moreland368e4602018-02-16 14:21:49 -0800790 out << "static ";
791 method->generateCppReturnType(out);
792 out << " _hidl_" << method->name() << "("
793 << "::android::hardware::IInterface* _hidl_this, "
794 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700795
Steven Moreland368e4602018-02-16 14:21:49 -0800796 if (!method->hasEmptyCppArgSignature()) {
797 out << ", ";
798 }
799 method->emitCppArgSignature(out);
800 out << ");\n";
801 },
802 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700803
Steven Moreland368e4602018-02-16 14:21:49 -0800804 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700805 method->generateCppSignature(out);
806 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700807 });
Steven Moreland9c387612016-09-07 09:54:26 -0700808
Andreas Huber881227d2016-08-02 14:20:21 -0700809 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100810 out << "private:\n";
811 out.indent();
812 out << "std::mutex _hidl_mMutex;\n"
813 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
814 << " _hidl_mDeathRecipients;\n";
815 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700816 out << "};\n\n";
817
818 enterLeaveNamespace(out, false /* enter */);
819
820 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700821}
822
Steven Moreland368e4602018-02-16 14:21:49 -0800823void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700824 std::string baseName = getBaseName();
825 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700826
Steven Morelanda885d252017-09-25 18:44:43 -0700827 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700828
Steven Moreland623c0042017-01-13 14:42:29 -0800829 out << "#define LOG_TAG \""
830 << mPackage.string() << "::" << baseName
831 << "\"\n\n";
832
Steven Moreland5add34d2018-11-08 16:31:30 -0800833 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100834 out << "#include <cutils/trace.h>\n";
835 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700836 out << "#include <hidl/Static.h>\n";
837 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700838 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700839 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700840 // This is a no-op for IServiceManager itself.
841 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
842
Yifan Hongeefe4f22017-01-04 15:32:42 -0800843 generateCppPackageInclude(out, mPackage, iface->getProxyName());
844 generateCppPackageInclude(out, mPackage, iface->getStubName());
845 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700846
847 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700848 generateCppPackageInclude(out,
849 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800850 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700851 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800852
853 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700854 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700855 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800856 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700857 }
858
859 out << "\n";
860
861 enterLeaveNamespace(out, true /* enter */);
862 out << "\n";
863
Neel Mehta9200af02019-07-19 13:24:57 -0700864 generateTypeSource(out, iface ? iface->definedName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700865
Steven Moreland368e4602018-02-16 14:21:49 -0800866 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700867 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700868
869 // need to be put here, generateStubSource is using this.
Neel Mehta9200af02019-07-19 13:24:57 -0700870 out << "const char* " << iface->definedName() << "::descriptor(\""
871 << iface->fqName().string() << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800872 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100873 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800874 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800875 out << "::android::hardware::details::getBnConstructorMap().set("
Neel Mehta9200af02019-07-19 13:24:57 -0700876 << iface->definedName() << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800877 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800878 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800879 out.indent([&] {
Neel Mehta9200af02019-07-19 13:24:57 -0700880 out << "return new " << iface->getStubName() << "(static_cast<"
881 << iface->definedName() << " *>(iIntf));\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800882 });
Yifan Hongb04de382017-02-06 15:31:52 -0800883 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800884 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800885 out << "::android::hardware::details::getBsConstructorMap().set("
Neel Mehta9200af02019-07-19 13:24:57 -0700886 << iface->definedName() << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800887 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800888 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800889 << gIBaseFqName.cppName()
890 << "> {\n";
891 out.indent([&] {
Neel Mehta9200af02019-07-19 13:24:57 -0700892 out << "return new " << iface->getPassthroughName() << "(static_cast<"
893 << iface->definedName() << " *>(iIntf));\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800894 });
Yifan Hongb04de382017-02-06 15:31:52 -0800895 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800896 });
Yifan Hong158655a2016-11-08 12:34:07 -0800897 });
Bernhard Rosenkränzera8be3492018-04-15 22:32:41 +0200898 out << "}\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100899 out << "__attribute__((destructor))";
900 out << "static void static_destructor() {\n";
901 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800902 out << "::android::hardware::details::getBnConstructorMap().erase("
Neel Mehta9200af02019-07-19 13:24:57 -0700903 << iface->definedName() << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800904 out << "::android::hardware::details::getBsConstructorMap().erase("
Neel Mehta9200af02019-07-19 13:24:57 -0700905 << iface->definedName() << "::descriptor);\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100906 });
Bernhard Rosenkränzera8be3492018-04-15 22:32:41 +0200907 out << "}\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800908
Steven Moreland368e4602018-02-16 14:21:49 -0800909 generateInterfaceSource(out);
910 generateProxySource(out, iface->fqName());
911 generateStubSource(out, iface);
912 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700913
Yifan Hongc8934042016-11-17 17:10:52 -0800914 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800915 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800916 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800917 std::string package = iface->fqName().package()
918 + iface->fqName().atVersion();
919
Yifan Hongeefe4f22017-01-04 15:32:42 -0800920 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800921 }
Steven Moreland40786312016-08-16 10:29:40 -0700922 }
923
Andreas Huber6755e9d2017-04-06 11:09:07 -0700924 HidlTypeAssertion::EmitAll(out);
925 out << "\n";
926
Andreas Huber881227d2016-08-02 14:20:21 -0700927 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700928}
929
Steven Moreland368e4602018-02-16 14:21:49 -0800930void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
931 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700932}
933
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700934void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
935 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700936 if (args.empty()) {
937 return;
938 }
939
940 for (const auto &arg : args) {
941 const Type &type = arg->type();
942
Yifan Hong3b320f82016-11-01 15:15:54 -0700943 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700944 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700945 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700946 << ";\n";
947 }
948
949 out << "\n";
950}
951
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700952void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
953 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
954 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700955 const Type &type = arg->type();
956
Andreas Huber881227d2016-08-02 14:20:21 -0700957 type.emitReaderWriter(
958 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700959 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700960 parcelObj,
961 parcelObjIsPointer,
962 isReader,
963 mode);
964}
965
Steven Moreland368e4602018-02-16 14:21:49 -0800966void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
967 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700968 method->generateCppSignature(out,
969 klassName,
970 true /* specify namespaces */);
971
Martijn Coenen115d4282016-12-19 05:14:04 +0100972 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -0700973 out.block([&] {
974 method->cppImpl(IMPL_PROXY, out);
975 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -0800976 return;
Martijn Coenen115d4282016-12-19 05:14:04 +0100977 }
978
Steven Morelandf16c5c02017-07-31 16:50:06 -0700979 out.block([&] {
980 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700981 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -0700982
983 method->generateCppReturnType(out);
984
985 out << " _hidl_out = "
986 << superInterface->fqName().cppNamespace()
987 << "::"
988 << superInterface->getProxyName()
989 << "::_hidl_"
990 << method->name()
991 << "(this, this";
992
993 if (!method->hasEmptyCppArgSignature()) {
994 out << ", ";
995 }
996
997 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
998 out << arg->name();
999 });
1000
1001 if (returnsValue && elidedReturn == nullptr) {
1002 if (!method->args().empty()) {
1003 out << ", ";
1004 }
1005 out << "_hidl_cb";
1006 }
1007
1008 out << ");\n\n";
1009
1010 out << "return _hidl_out;\n";
1011 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001012}
1013
Steven Moreland368e4602018-02-16 14:21:49 -08001014void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001015 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001016 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001017 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001018 }
1019
1020 method->generateCppReturnType(out);
1021
1022 out << klassName
1023 << "::_hidl_"
1024 << method->name()
1025 << "("
1026 << "::android::hardware::IInterface *_hidl_this, "
1027 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1028
1029 if (!method->hasEmptyCppArgSignature()) {
1030 out << ", ";
1031 }
1032
1033 method->emitCppArgSignature(out);
1034 out << ") {\n";
1035
1036 out.indent();
1037
1038 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1039 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1040 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1041 out << "#else\n";
1042 out << "(void) _hidl_this_instrumentor;\n";
1043 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1044
1045 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001046 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001047 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1048
Steven Moreland92a08a72017-07-31 14:57:37 -07001049 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001050 out,
1051 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001052 method,
1053 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001054
1055 out << "::android::hardware::Parcel _hidl_data;\n";
1056 out << "::android::hardware::Parcel _hidl_reply;\n";
1057 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001058 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001059 out << "::android::hardware::Status _hidl_status;\n\n";
1060
Steven Moreland48cc6042019-04-30 11:28:56 -07001061 if (!hasCallback) {
1062 declareCppReaderLocals(
1063 out, method->results(), true /* forResults */);
1064 }
Yifan Hong068c5522016-10-31 14:07:25 -07001065
1066 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001067 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001068 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001069 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1070
Martijn Coenenfff73352017-01-04 16:36:31 +01001071 bool hasInterfaceArgument = false;
Steven Moreland8249f0a2019-05-28 17:25:27 -07001072
Yifan Hong068c5522016-10-31 14:07:25 -07001073 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001074 if (arg->type().isInterface()) {
1075 hasInterfaceArgument = true;
1076 }
Yifan Hong068c5522016-10-31 14:07:25 -07001077 emitCppReaderWriter(
1078 out,
1079 "_hidl_data",
1080 false /* parcelObjIsPointer */,
1081 arg,
1082 false /* reader */,
1083 Type::ErrorMode_Goto,
1084 false /* addPrefixToName */);
1085 }
1086
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001087 if (hasInterfaceArgument) {
1088 // Start binder threadpool to handle incoming transactions
1089 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1090 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001091 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001092 << method->getSerialId()
1093 << " /* "
1094 << method->name()
1095 << " */, _hidl_data, &_hidl_reply";
1096
1097 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001098 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001099 } else {
1100 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001101 }
Yifan Hong068c5522016-10-31 14:07:25 -07001102
Steven Moreland48cc6042019-04-30 11:28:56 -07001103 if (hasCallback) {
1104 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1105 out.indent();
1106 declareCppReaderLocals(
1107 out, method->results(), true /* forResults */);
1108 out.endl();
1109 } else {
1110 out << ");\n";
1111 out << "if (_hidl_transact_err != ::android::OK) \n";
1112 out.block([&] {
1113 out << "_hidl_err = _hidl_transact_err;\n";
1114 out << "goto _hidl_error;\n";
1115 }).endl().endl();
1116 }
Yifan Hong068c5522016-10-31 14:07:25 -07001117
1118 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001119 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001120
Steven Moreland48cc6042019-04-30 11:28:56 -07001121 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1122 Type::handleError(out, errorMode);
1123
1124 if (hasCallback) {
1125 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1126 } else {
1127 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1128 }
Yifan Hong068c5522016-10-31 14:07:25 -07001129
Yifan Hong068c5522016-10-31 14:07:25 -07001130 for (const auto &arg : method->results()) {
1131 emitCppReaderWriter(
1132 out,
1133 "_hidl_reply",
1134 false /* parcelObjIsPointer */,
1135 arg,
1136 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001137 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001138 true /* addPrefixToName */);
1139 }
1140
Yifan Hong068c5522016-10-31 14:07:25 -07001141 if (returnsValue && elidedReturn == nullptr) {
1142 out << "_hidl_cb(";
1143
Yifan Hong932464e2017-03-30 15:40:22 -07001144 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001145 if (arg->type().resultNeedsDeref()) {
1146 out << "*";
1147 }
1148 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001149 });
Yifan Hong068c5522016-10-31 14:07:25 -07001150
1151 out << ");\n\n";
1152 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001153 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001154
Steven Moreland92a08a72017-07-31 14:57:37 -07001155 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001156 out,
1157 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001158 method,
1159 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001160
Steven Moreland48cc6042019-04-30 11:28:56 -07001161 if (hasCallback) {
1162 out.unindent();
1163 out << "});\n";
1164 out << "if (_hidl_transact_err != ::android::OK) ";
1165 out.block([&] {
1166 out << "_hidl_err = _hidl_transact_err;\n";
1167 out << "goto _hidl_error;\n";
1168 }).endl().endl();
1169 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1170 }
1171
Yifan Hong068c5522016-10-31 14:07:25 -07001172 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001173 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001174 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001175 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1176 } else {
Yifan Hong068c5522016-10-31 14:07:25 -07001177 out << "return ::android::hardware::Return<void>();\n\n";
1178 }
1179
1180 out.unindent();
1181 out << "_hidl_error:\n";
1182 out.indent();
1183 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1184 out << "return ::android::hardware::Return<";
1185 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001186 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001187 } else {
1188 out << "void";
1189 }
1190 out << ">(_hidl_status);\n";
1191
1192 out.unindent();
1193 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001194}
1195
Steven Moreland368e4602018-02-16 14:21:49 -08001196void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001197 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001198
1199 out << klassName
1200 << "::"
1201 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001202 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001203
1204 out.indent();
1205 out.indent();
1206
1207 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001208 << "<"
1209 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001210 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001211 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001212 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001213 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001214 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001215 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001216
Andreas Huber881227d2016-08-02 14:20:21 -07001217 out.unindent();
1218 out.unindent();
1219 out << "}\n\n";
1220
Steven Moreland596d20e2019-06-07 11:52:21 -07001221 out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1222 out.block([&] {
1223 out.block([&] {
1224 // if unlinkToDeath is not used, remove strong cycle between
1225 // this and hidl_binder_death_recipient
1226 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1227 out << "_hidl_mDeathRecipients.clear();\n";
1228 }).endl().endl();
1229
1230 out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1231 }).endl();
1232
Steven Moreland368e4602018-02-16 14:21:49 -08001233 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001234 [&](const Method* method, const Interface* superInterface) {
1235 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001236 },
1237 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001238
Steven Moreland368e4602018-02-16 14:21:49 -08001239 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1240 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001241 });
Andreas Huber881227d2016-08-02 14:20:21 -07001242}
1243
Steven Moreland368e4602018-02-16 14:21:49 -08001244void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Neel Mehta9200af02019-07-19 13:24:57 -07001245 const std::string interfaceName = iface->definedName();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001246 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001247
Steven Moreland40786312016-08-16 10:29:40 -07001248 out << klassName
1249 << "::"
1250 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001251 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001252
1253 out.indent();
1254 out.indent();
1255
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001256 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001257 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001258 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001259 out << ": "
1260 << gIBaseFqName.getInterfaceStubFqName().cppName()
1261 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001262 }
1263
1264 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001265 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001266 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001267 << "\") { \n";
1268 out.indent();
1269 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Moreland0e0935c2019-09-18 12:05:36 -07001270 out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
Martijn Coenenb4d77952017-05-03 13:44:29 -07001271 out << "mSchedPolicy = prio.sched_policy;\n";
1272 out << "mSchedPriority = prio.prio;\n";
Steven Moreland0e0935c2019-09-18 12:05:36 -07001273 out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001274 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001275
1276 out.unindent();
1277 out.unindent();
1278 out << "}\n\n";
1279
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001280 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001281 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001282 // class properly.
1283 out << klassName
1284 << "::"
1285 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001286 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1287 << " const std::string &HidlInstrumentor_package,"
1288 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001289
1290 out.indent();
1291 out.indent();
1292
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001293 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001294 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001295 out.indent();
1296 out << "_hidl_mImpl = _hidl_impl;\n";
1297 out.unindent();
1298
1299 out.unindent();
1300 out.unindent();
1301 out << "}\n\n";
1302 }
1303
Steven Moreland57a89362017-07-21 19:29:54 +00001304 out << klassName << "::~" << klassName << "() ";
1305 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001306 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1307 })
1308 .endl()
1309 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001310
Steven Moreland368e4602018-02-16 14:21:49 -08001311 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001312 [&](const Method* method, const Interface* superInterface) {
1313 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001314 },
1315 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001316
Steven Moreland368e4602018-02-16 14:21:49 -08001317 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001318 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001319 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001320 }
1321 method->generateCppSignature(out, iface->getStubName());
1322 out << " ";
1323 out.block([&] {
1324 method->cppImpl(IMPL_STUB_IMPL, out);
1325 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001326 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001327
Andreas Huber881227d2016-08-02 14:20:21 -07001328 out << "::android::status_t " << klassName << "::onTransact(\n";
1329
1330 out.indent();
1331 out.indent();
1332
Iliyan Malchev549e2592016-08-10 08:59:12 -07001333 out << "uint32_t _hidl_code,\n"
1334 << "const ::android::hardware::Parcel &_hidl_data,\n"
1335 << "::android::hardware::Parcel *_hidl_reply,\n"
1336 << "uint32_t _hidl_flags,\n"
1337 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001338
1339 out.unindent();
1340
Iliyan Malchev549e2592016-08-10 08:59:12 -07001341 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001342 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001343 out.indent();
1344
Yifan Hong10fe0b52016-10-19 14:20:17 -07001345 for (const auto &tuple : iface->allMethodsFromRoot()) {
1346 const Method *method = tuple.method();
1347 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001348
Howard Chen71f289f2017-08-29 17:35:01 +08001349 if (!isIBase() && method->isHidlReserved()) {
1350 continue;
1351 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001352 out << "case "
1353 << method->getSerialId()
1354 << " /* "
1355 << method->name()
1356 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001357
Yifan Hong10fe0b52016-10-19 14:20:17 -07001358 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001359
Steven Moreland368e4602018-02-16 14:21:49 -08001360 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001361
1362 out.unindent();
1363 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001364 }
1365
1366 out << "default:\n{\n";
1367 out.indent();
1368
Martijn Coenen225bc922017-06-27 14:39:46 -07001369 if (iface->isIBase()) {
1370 out << "(void)_hidl_flags;\n";
1371 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1372 } else {
1373 out << "return ";
1374 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1375 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001376
Martijn Coenen225bc922017-06-27 14:39:46 -07001377 out.indent();
1378 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001379
Martijn Coenen225bc922017-06-27 14:39:46 -07001380 out << "_hidl_code, _hidl_data, _hidl_reply, "
1381 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001382
Martijn Coenen225bc922017-06-27 14:39:46 -07001383 out.unindent();
1384 out.unindent();
1385 }
Andreas Huber881227d2016-08-02 14:20:21 -07001386
1387 out.unindent();
1388 out << "}\n";
1389
1390 out.unindent();
1391 out << "}\n\n";
1392
Yifan Honga018ed52016-12-13 16:35:08 -08001393 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1394 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1395 out.indent(2, [&] {
1396 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1397 out << "_hidl_reply);\n";
1398 });
1399 });
Andreas Huber881227d2016-08-02 14:20:21 -07001400
Iliyan Malchev549e2592016-08-10 08:59:12 -07001401 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001402
1403 out.unindent();
1404 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001405}
1406
Steven Moreland368e4602018-02-16 14:21:49 -08001407void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1408 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001409 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1410 method->cppImpl(IMPL_STUB, out);
1411 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001412 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001413 }
1414
Steven Morelandf16c5c02017-07-31 16:50:06 -07001415 out << "_hidl_err = "
1416 << superInterface->fqName().cppNamespace()
1417 << "::"
1418 << superInterface->getStubName()
1419 << "::_hidl_"
1420 << method->name()
1421 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1422 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001423}
1424
Steven Moreland368e4602018-02-16 14:21:49 -08001425void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001426 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001427 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001428 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001429 }
1430
Steven Morelandf8197902018-01-30 15:38:37 -08001431 const std::string& klassName = fqName.getInterfaceStubName();
1432
Steven Morelandf16c5c02017-07-31 16:50:06 -07001433 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1434
1435 out.indent();
1436 out.indent();
1437
1438 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1439 << "const ::android::hardware::Parcel &_hidl_data,\n"
1440 << "::android::hardware::Parcel *_hidl_reply,\n"
1441 << "TransactCallback _hidl_cb) {\n";
1442
1443 out.unindent();
1444
1445 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1446 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1447 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1448 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1449
1450 out << "::android::status_t _hidl_err = ::android::OK;\n";
1451
Yifan Hongeefe4f22017-01-04 15:32:42 -08001452 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001453 << klassName
1454 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001455
Andreas Huber881227d2016-08-02 14:20:21 -07001456 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001457 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001458 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001459 out.unindent();
1460 out << "}\n\n";
1461
Andreas Huber5e44a292016-09-27 14:52:39 -07001462 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001463
Andreas Huber881227d2016-08-02 14:20:21 -07001464 for (const auto &arg : method->args()) {
1465 emitCppReaderWriter(
1466 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001467 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001468 false /* parcelObjIsPointer */,
1469 arg,
1470 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001471 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001472 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001473 }
1474
Steven Moreland92a08a72017-07-31 14:57:37 -07001475 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001476 out,
1477 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001478 method,
1479 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001480
Andreas Huber881227d2016-08-02 14:20:21 -07001481 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001482 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001483
1484 std::string callee;
1485
1486 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1487 callee = "_hidl_this";
1488 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001489 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001490 }
Andreas Huber881227d2016-08-02 14:20:21 -07001491
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001492 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001493 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001494 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001495 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001496 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001497 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001498 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001499
Yifan Hong932464e2017-03-30 15:40:22 -07001500 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001501 if (arg->type().resultNeedsDeref()) {
1502 out << "*";
1503 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001504 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001505 });
Andreas Huber881227d2016-08-02 14:20:21 -07001506
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001507 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001508
Yifan Hong859e53f2016-11-14 19:08:24 -08001509 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1510 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001511
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001512 elidedReturn->type().emitReaderWriter(
1513 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001514 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001515 "_hidl_reply",
1516 true, /* parcelObjIsPointer */
1517 false, /* isReader */
Steven Moreland70f66252020-01-09 17:26:57 -08001518 Type::ErrorMode_Goto);
1519
1520 out.unindent();
1521 out << "_hidl_error:\n";
1522 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001523
Steven Moreland92a08a72017-07-31 14:57:37 -07001524 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001525 out,
1526 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001527 method,
1528 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001529
Steven Moreland70f66252020-01-09 17:26:57 -08001530 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001531 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001532 } else {
1533 if (returnsValue) {
1534 out << "bool _hidl_callbackCalled = false;\n\n";
1535 }
Andreas Huber881227d2016-08-02 14:20:21 -07001536
Steven Moreland30232dc2019-03-05 19:39:10 -08001537 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1538 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001539
Yifan Hong932464e2017-03-30 15:40:22 -07001540 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001541 if (arg->type().resultNeedsDeref()) {
1542 out << "*";
1543 }
1544
1545 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001546 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001547
1548 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001549 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001550 out << ", ";
1551 }
1552
1553 out << "[&](";
1554
Yifan Hong932464e2017-03-30 15:40:22 -07001555 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001556 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001557 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001558
1559 out << ") {\n";
1560 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001561 out << "if (_hidl_callbackCalled) {\n";
1562 out.indent();
1563 out << "LOG_ALWAYS_FATAL(\""
1564 << method->name()
1565 << ": _hidl_cb called a second time, but must be called once.\");\n";
1566 out.unindent();
1567 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001568 out << "_hidl_callbackCalled = true;\n\n";
1569
Yifan Hong859e53f2016-11-14 19:08:24 -08001570 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1571 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001572
1573 for (const auto &arg : method->results()) {
1574 emitCppReaderWriter(
1575 out,
1576 "_hidl_reply",
1577 true /* parcelObjIsPointer */,
1578 arg,
1579 false /* reader */,
Steven Moreland70f66252020-01-09 17:26:57 -08001580 Type::ErrorMode_Goto,
Yifan Honga47eef32016-12-12 10:38:54 -08001581 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001582 }
1583
Steven Moreland70f66252020-01-09 17:26:57 -08001584 if (!method->results().empty()) {
1585 out.unindent();
1586 out << "_hidl_error:\n";
1587 out.indent();
1588 }
1589
Steven Moreland92a08a72017-07-31 14:57:37 -07001590 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001591 out,
1592 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001593 method,
1594 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001595
Steven Moreland70f66252020-01-09 17:26:57 -08001596 out << "if (_hidl_err != ::android::OK) { return; }\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001597 out << "_hidl_cb(*_hidl_reply);\n";
1598
1599 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001600 out << "});\n\n";
1601 } else {
1602 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001603 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001604 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001605 out,
1606 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001607 method,
1608 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001609 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001610
Steven Moreland30232dc2019-03-05 19:39:10 -08001611 out << "_hidl_ret.assertOk();\n";
1612
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613 if (returnsValue) {
1614 out << "if (!_hidl_callbackCalled) {\n";
1615 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001616 out << "LOG_ALWAYS_FATAL(\""
1617 << method->name()
1618 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001619 out.unindent();
1620 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001621 } else {
1622 out << "::android::hardware::writeToParcel("
1623 << "::android::hardware::Status::ok(), "
1624 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001625 }
Andreas Huber881227d2016-08-02 14:20:21 -07001626 }
1627
Steven Morelandf16c5c02017-07-31 16:50:06 -07001628 out << "return _hidl_err;\n";
1629 out.unindent();
1630 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001631}
1632
Steven Moreland368e4602018-02-16 14:21:49 -08001633void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001634 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001635 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001636 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001637 }
1638
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001639 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001640 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001641
Yifan Hongeefe4f22017-01-04 15:32:42 -08001642 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001643
Steven Moreland69e7c702016-09-09 11:16:32 -07001644 const std::string guard = makeHeaderGuard(klassName);
1645
1646 out << "#ifndef " << guard << "\n";
1647 out << "#define " << guard << "\n\n";
1648
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
Neel Mehta9200af02019-07-19 13:24:57 -07001653 generateCppPackageInclude(out, mPackage, iface->definedName());
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
Neel Mehta9200af02019-07-19 13:24:57 -07001662 out << "struct " << klassName << " : " << iface->definedName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001663 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001664
1665 out.indent();
Neel Mehta9200af02019-07-19 13:24:57 -07001666 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001667 << "> impl);\n";
1668
Steven Moreland0b843772017-06-23 16:33:38 -07001669 out.endl();
1670 generateTemplatizationLink(out);
Diogo Ferreira604fe012019-10-17 12:32:00 +01001671 generateCppTag(out, "::android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001672
Steven Moreland616cf4d2018-10-02 13:52:18 -07001673 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1674 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001675 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001676
Steven Moreland69e7c702016-09-09 11:16:32 -07001677 out.unindent();
1678 out << "private:\n";
1679 out.indent();
Neel Mehta9200af02019-07-19 13:24:57 -07001680 out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001681
Neel Mehta19f79792019-05-21 13:39:32 -07001682 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001683
Neel Mehta19f79792019-05-21 13:39:32 -07001684 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001685
Neel Mehta19f79792019-05-21 13:39:32 -07001686 out << "::android::hardware::Return<void> addOnewayTask("
1687 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001688
1689 out.unindent();
1690
1691 out << "};\n\n";
1692
1693 enterLeaveNamespace(out, false /* enter */);
1694
1695 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001696}
1697
Steven Moreland368e4602018-02-16 14:21:49 -08001698void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001699 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001700
Yifan Hong2d7126b2016-10-20 15:12:57 -07001701 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001702 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001703
Steven Moreland368e4602018-02-16 14:21:49 -08001704 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001705 bool reserved = method->isHidlReserved();
1706
1707 if (!reserved) {
1708 out << "// no default implementation for: ";
1709 }
Neel Mehta9200af02019-07-19 13:24:57 -07001710 method->generateCppSignature(out, iface->definedName());
Steven Morelandd4b068a2017-03-20 06:30:51 -07001711 if (reserved) {
1712 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001713 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001714 }).endl();
1715 }
1716
1717 out << "\n";
1718
Steven Moreland368e4602018-02-16 14:21:49 -08001719 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001720 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001721
Yifan Hong3d746092016-12-07 14:26:33 -08001722 for (const Interface *superType : iface->typeChain()) {
Neel Mehta9200af02019-07-19 13:24:57 -07001723 out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1724 << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1725 << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001726 out.indent();
1727 if (iface == superType) {
1728 out << "return parent;\n";
1729 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001730 out << "return ::android::hardware::details::castInterface<";
Neel Mehta9200af02019-07-19 13:24:57 -07001731 out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1732 << iface->getProxyName() << ">(\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001733 out.indent();
1734 out.indent();
1735 out << "parent, \""
1736 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001737 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001738 out.unindent();
1739 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001740 }
Yifan Hong3d746092016-12-07 14:26:33 -08001741 out.unindent();
1742 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001743 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001744}
1745
Steven Moreland368e4602018-02-16 14:21:49 -08001746void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001747 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001748
Yifan Hongeefe4f22017-01-04 15:32:42 -08001749 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001750
Neel Mehta19f79792019-05-21 13:39:32 -07001751 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1752 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
Neel Mehta9200af02019-07-19 13:24:57 -07001753 << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001754
1755 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1756
Yifan Hong2cbc1472016-10-25 19:02:40 -07001757 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001758
Neel Mehta19f79792019-05-21 13:39:32 -07001759 out << "::android::hardware::Return<void> " << klassName
1760 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1761 out.indent();
1762 out << "if (!mOnewayQueue.push(fun)) {\n";
1763 out.indent();
1764 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1765 out.indent();
1766 out.indent();
1767 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1768 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1769 out.unindent();
1770 out.unindent();
1771 out.unindent();
1772 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001773
Neel Mehta19f79792019-05-21 13:39:32 -07001774 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001775
Neel Mehta19f79792019-05-21 13:39:32 -07001776 out.unindent();
1777 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001778}
1779
Steven Moreland92a08a72017-07-31 14:57:37 -07001780void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001781 InstrumentationEvent event,
1782 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001783 const Interface* iface = mRootScope.getInterface();
Neel Mehta9200af02019-07-19 13:24:57 -07001784 std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001785 switch (event) {
1786 case SERVER_API_ENTRY:
1787 {
1788 out << "atrace_begin(ATRACE_TAG_HAL, \""
1789 << baseString + "::server\");\n";
1790 break;
1791 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001792 case PASSTHROUGH_ENTRY:
1793 {
1794 out << "atrace_begin(ATRACE_TAG_HAL, \""
1795 << baseString + "::passthrough\");\n";
1796 break;
1797 }
1798 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001799 case PASSTHROUGH_EXIT:
1800 {
1801 out << "atrace_end(ATRACE_TAG_HAL);\n";
1802 break;
1803 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001804 // client uses scope because of gotos
1805 // this isn't done for server because the profiled code isn't alone in its scope
1806 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1807 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001808 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1809 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001810 break;
1811 }
1812 case CLIENT_API_EXIT:
1813 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001814 default:
1815 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001816 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001817 }
1818 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001819}
1820
Steven Moreland92a08a72017-07-31 14:57:37 -07001821void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001822 Formatter &out,
1823 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001824 const Method *method,
1825 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001826 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001827
Steven Moreland30b76e92017-06-02 18:52:24 -07001828 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001829 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1830 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001831 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001832 std::string event_str = "";
1833 switch (event) {
1834 case SERVER_API_ENTRY:
1835 {
1836 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1837 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001838 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001839 << (arg->type().resultNeedsDeref() ? "" : "&")
1840 << arg->name()
1841 << ");\n";
1842 }
1843 break;
1844 }
1845 case SERVER_API_EXIT:
1846 {
1847 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001848 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001849 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001850 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001851 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001852 }
1853 break;
1854 }
1855 case CLIENT_API_ENTRY:
1856 {
1857 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1858 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001859 out << "_hidl_args.push_back((void *)&"
1860 << arg->name()
1861 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001862 }
1863 break;
1864 }
1865 case CLIENT_API_EXIT:
1866 {
1867 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1868 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001869 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001870 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001871 << "_hidl_out_"
1872 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001873 << ");\n";
1874 }
1875 break;
1876 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001877 case PASSTHROUGH_ENTRY:
1878 {
1879 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1880 for (const auto &arg : method->args()) {
1881 out << "_hidl_args.push_back((void *)&"
1882 << arg->name()
1883 << ");\n";
1884 }
1885 break;
1886 }
1887 case PASSTHROUGH_EXIT:
1888 {
1889 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001890 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001891 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001892 << arg->name()
1893 << ");\n";
1894 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001895 break;
1896 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001897 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001898 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001899 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001900 }
1901 }
1902
Steven Moreland1ab31442016-11-03 18:37:51 -07001903 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001904 out.indent();
Neel Mehta9200af02019-07-19 13:24:57 -07001905 out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1906 << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1907 << "\", \"" << method->name() << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001908 out.unindent();
1909 out << "}\n";
1910 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001911 out << "}\n";
1912 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001913}
1914
Andreas Huber881227d2016-08-02 14:20:21 -07001915} // namespace android