blob: a23883817508b20bd4bfe17268d04da5eb99a7f2 [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
Andreas Huber737080b2016-08-02 15:38:04 -070038void AST::getPackageComponents(
39 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070040 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070041}
42
43void AST::getPackageAndVersionComponents(
44 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070045 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070046}
47
Steven Moreland5708edf2016-11-04 15:33:31 +000048std::string AST::makeHeaderGuard(const std::string &baseName,
49 bool indicateGenerated) const {
50 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070051
Steven Moreland5708edf2016-11-04 15:33:31 +000052 if (indicateGenerated) {
53 guard += "HIDL_GENERATED_";
54 }
55
56 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070057 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000058 guard += StringHelper::Uppercase(baseName);
59 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070060
61 return guard;
62}
63
Steven Morelandee88eed2016-10-31 17:49:00 -070064void AST::generateCppPackageInclude(
65 Formatter &out,
66 const FQName &package,
67 const std::string &klass) {
68
69 out << "#include <";
70
71 std::vector<std::string> components;
72 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
73
74 for (const auto &component : components) {
75 out << component << "/";
76 }
77
78 out << klass
79 << ".h>\n";
80}
81
Andreas Huber881227d2016-08-02 14:20:21 -070082void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
83 std::vector<std::string> packageComponents;
84 getPackageAndVersionComponents(
85 &packageComponents, true /* cpp_compatible */);
86
87 if (enter) {
88 for (const auto &component : packageComponents) {
89 out << "namespace " << component << " {\n";
90 }
91 } else {
92 for (auto it = packageComponents.rbegin();
93 it != packageComponents.rend();
94 ++it) {
95 out << "} // namespace " << *it << "\n";
96 }
97 }
98}
99
Steven Moreland038903b2017-03-30 12:11:24 -0700100static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
101 const std::string functionName = isTry ? "tryGetService" : "getService";
102
Steven Moreland7645fbd2019-03-12 18:49:28 -0700103 if (isTry) {
104 DocComment(
105 "This gets the service of this type with the specified instance name. If the\n"
106 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
107 "device, this will return nullptr. This is useful when you don't want to block\n"
108 "during device boot. If getStub is true, this will try to return an unwrapped\n"
109 "passthrough implementation in the same process. This is useful when getting an\n"
110 "implementation from the same partition/compilation group.\n\n"
Neel Mehta291d02e2019-06-06 17:51:07 -0700111 "In general, prefer getService(std::string,bool)",
112 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700113 .emit(out);
114 } else {
115 DocComment(
116 "This gets the service of this type with the specified instance name. If the\n"
117 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
118 "nullptr. If the service is not available, this will wait for the service to\n"
119 "become available. If the service is a lazy service, this will start the service\n"
120 "and return when it becomes available. If getStub is true, this will try to\n"
121 "return an unwrapped passthrough implementation in the same process. This is\n"
Neel Mehta291d02e2019-06-06 17:51:07 -0700122 "useful when getting an implementation from the same partition/compilation group.",
123 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700124 .emit(out);
125 }
Steven Moreland038903b2017-03-30 12:11:24 -0700126 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800127 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Neel Mehta291d02e2019-06-06 17:51:07 -0700128 DocComment("Deprecated. See " + functionName + "(std::string, bool)", HIDL_LOCATION_HERE)
129 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700130 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800131 << "const char serviceName[], bool getStub=false)"
132 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700133 << " return " << functionName << "(str, getStub); }\n";
Neel Mehta291d02e2019-06-06 17:51:07 -0700134 DocComment("Deprecated. See " + functionName + "(std::string, bool)", HIDL_LOCATION_HERE)
135 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700136 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800137 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
138 // without c_str the std::string constructor is ambiguous
139 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700140 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700141 DocComment("Calls " + functionName +
Neel Mehta291d02e2019-06-06 17:51:07 -0700142 "(\"default\", bool). This is the recommended instance name for singleton "
143 "services.",
144 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700145 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700146 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
147 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
148}
149
150static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
151 declareGetService(out, interfaceName, true /* isTry */);
152 declareGetService(out, interfaceName, false /* isTry */);
153
Steven Moreland7645fbd2019-03-12 18:49:28 -0700154 DocComment(
155 "Registers a service with the service manager. For Trebilized devices, the service\n"
Neel Mehta291d02e2019-06-06 17:51:07 -0700156 "must also be in the VINTF manifest.",
157 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700158 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700159 out << "__attribute__ ((warn_unused_result))"
160 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Neel Mehta291d02e2019-06-06 17:51:07 -0700161 DocComment("Registers for notifications for when a service is registered.", HIDL_LOCATION_HERE)
162 .emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800163 out << "static bool registerForNotifications(\n";
164 out.indent(2, [&] {
165 out << "const std::string &serviceName,\n"
166 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
167 << "&notification);\n";
168 });
169
170}
171
Steven Moreland038903b2017-03-30 12:11:24 -0700172static void implementGetService(Formatter &out,
173 const FQName &fqName,
174 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800175
176 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700177 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800178
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700179 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000180 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800181 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700182 out << "return ::android::hardware::details::getServiceInternal<"
183 << fqName.getInterfaceProxyName()
184 << ">(serviceName, "
185 << (!isTry ? "true" : "false") // retry
186 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800187 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700188}
189
190static void implementServiceManagerInteractions(Formatter &out,
191 const FQName &fqName, const std::string &package) {
192
193 const std::string interfaceName = fqName.getInterfaceName();
194
195 implementGetService(out, fqName, true /* isTry */);
196 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800197
Yifan Hongeefe4f22017-01-04 15:32:42 -0800198 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800199 << "const std::string &serviceName) ";
200 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700201 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800202 }).endl().endl();
203
Yifan Hongeefe4f22017-01-04 15:32:42 -0800204 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800205 out.indent(2, [&] {
206 out << "const std::string &serviceName,\n"
207 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
208 << "&notification) ";
209 });
210 out.block([&] {
211 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
212 out.indent(2, [&] {
213 out << "= ::android::hardware::defaultServiceManager();\n";
214 });
215 out.sIf("sm == nullptr", [&] {
216 out << "return false;\n";
217 }).endl();
218 out << "::android::hardware::Return<bool> success =\n";
219 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800220 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800221 out.indent(2, [&] {
222 out << "serviceName, notification);\n";
223 });
224 });
225 out << "return success.isOk() && success;\n";
226 }).endl().endl();
227}
228
Steven Moreland368e4602018-02-16 14:21:49 -0800229void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700230 const Interface *iface = getInterface();
Neel Mehta257cce02019-07-19 13:24:57 -0700231 std::string ifaceName = iface ? iface->definedName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700232 const std::string guard = makeHeaderGuard(ifaceName);
233
234 out << "#ifndef " << guard << "\n";
235 out << "#define " << guard << "\n\n";
236
Andreas Huber737080b2016-08-02 15:38:04 -0700237 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700238 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700239 }
240
241 if (!mImportedNames.empty()) {
242 out << "\n";
243 }
244
Steven Moreland19f11b52017-05-12 18:22:21 -0700245 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800246 if (isIBase()) {
247 out << "// skipped #include IServiceNotification.h\n\n";
248 } else {
249 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
250 }
Steven Moreland0693f312016-11-09 15:06:14 -0800251 }
252
Yifan Hongc8934042016-11-17 17:10:52 -0800253 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700254 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700255
Steven Moreland19f11b52017-05-12 18:22:21 -0700256 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200257 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700258 }
259
Martijn Coenenaf712c02016-11-16 15:26:27 +0100260 out << "#include <utils/NativeHandle.h>\n";
261 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700262
263 enterLeaveNamespace(out, true /* enter */);
264 out << "\n";
265
Steven Moreland19f11b52017-05-12 18:22:21 -0700266 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700267 iface->emitDocComment(out);
268
Andreas Huber881227d2016-08-02 14:20:21 -0700269 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700270 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700271
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700272 const Interface *superType = iface->superType();
273
Yi Kong56758da2018-07-24 16:21:37 -0700274 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800275 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700276 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000277 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700278 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700279 }
280
281 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700282
283 out.indent();
284
Neel Mehta291d02e2019-06-06 17:51:07 -0700285 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.",
286 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700287 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700288 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700289
Neel Mehta291d02e2019-06-06 17:51:07 -0700290 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"",
291 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700292 .emit(out);
293 out << "static const char* descriptor;\n\n";
294
Steven Moreland70cb55e2019-03-12 17:20:54 -0700295 iface->emitTypeDeclarations(out);
296 } else {
297 mRootScope.emitTypeDeclarations(out);
298 }
Andreas Huber881227d2016-08-02 14:20:21 -0700299
Steven Moreland19f11b52017-05-12 18:22:21 -0700300 if (iface) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700301 DocComment(
Neel Mehta291d02e2019-06-06 17:51:07 -0700302 "Returns whether this object's implementation is outside of the current process.",
303 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700304 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800305 out << "virtual bool isRemote() const ";
306 if (!isIBase()) {
307 out << "override ";
308 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700309 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800310
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700311 for (const auto& tuple : iface->allMethodsFromRoot()) {
312 const Method* method = tuple.method();
313
Andreas Huber881227d2016-08-02 14:20:21 -0700314 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700315
Andreas Huber881227d2016-08-02 14:20:21 -0700316 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700317 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800318
319 if (elidedReturn == nullptr && returnsValue) {
Neel Mehta291d02e2019-06-06 17:51:07 -0700320 DocComment("Return callback for " + method->name(), HIDL_LOCATION_HERE).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800321 out << "using "
322 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700323 << "_cb = std::function<void(";
324 method->emitCppResultSignature(out, true /* specify namespaces */);
325 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800326 }
Andreas Huber881227d2016-08-02 14:20:21 -0700327
Steven Moreland49bad8d2018-05-17 15:45:26 -0700328 method->emitDocComment(out);
329
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700330 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700331 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700332 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700333 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700334 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700335 }
336
337 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700338 << "(";
339 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700340 out << ")";
341 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800342 if (!isIBase()) {
343 out << " override";
344 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700345 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700346 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700347 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700348 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700349 }
Steven Moreland40786312016-08-16 10:29:40 -0700350
Steven Moreland7645fbd2019-03-12 18:49:28 -0700351 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800352 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700353
Yifan Hong3d746092016-12-07 14:26:33 -0800354 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700355 DocComment(
356 "This performs a checked cast based on what the underlying implementation "
Neel Mehta291d02e2019-06-06 17:51:07 -0700357 "actually is.",
358 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700359 .emit(out);
Yifan Hong200209c2017-03-29 03:39:09 -0700360 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800361 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700362 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800363 << superType->getCppArgumentType()
364 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700365 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700366 }
367
Yifan Hongc8934042016-11-17 17:10:52 -0800368 if (isIBase()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700369 out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800370 } else {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700371 out << "\n// helper methods for interactions with the hwservicemanager\n";
Neel Mehta257cce02019-07-19 13:24:57 -0700372 declareServiceManagerInteractions(out, iface->definedName());
Yifan Hongc8934042016-11-17 17:10:52 -0800373 }
Andreas Huber881227d2016-08-02 14:20:21 -0700374 }
375
Steven Moreland19f11b52017-05-12 18:22:21 -0700376 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700377 out.unindent();
378
Andreas Hubere3f769a2016-10-10 10:54:44 -0700379 out << "};\n\n";
380 }
381
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700382 out << "//\n";
383 out << "// type declarations for package\n";
384 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800385 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700386 out << "//\n";
387 out << "// type header definitions for package\n";
388 out << "//\n\n";
389 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700390
391 out << "\n";
392 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700393 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700394
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700395 out << "//\n";
396 out << "// global type declarations for package\n";
397 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800398 mRootScope.emitGlobalTypeDeclarations(out);
399
Andreas Huber881227d2016-08-02 14:20:21 -0700400 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700401}
402
Steven Moreland368e4602018-02-16 14:21:49 -0800403void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700404 const Interface *iface = getInterface();
405 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700406
Steven Moreland40786312016-08-16 10:29:40 -0700407 const std::string guard = makeHeaderGuard(klassName);
408
409 out << "#ifndef " << guard << "\n";
410 out << "#define " << guard << "\n\n";
411
Neel Mehta257cce02019-07-19 13:24:57 -0700412 generateCppPackageInclude(out, mPackage, iface ? iface->definedName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700413
Steven Morelandee88eed2016-10-31 17:49:00 -0700414 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700415
416 for (const auto &item : mImportedNames) {
417 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800418 generateCppPackageInclude(out, item, "hwtypes");
419 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800420 generateCppPackageInclude(out, item, item.getInterfaceStubName());
421 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700422 }
Steven Moreland40786312016-08-16 10:29:40 -0700423 }
424
425 out << "\n";
426
Martijn Coenen93915102016-09-01 01:35:52 +0200427 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700428 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100429 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700430
431 out << "\n";
432
433 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700434
Steven Moreland368e4602018-02-16 14:21:49 -0800435 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700436
437 enterLeaveNamespace(out, false /* enter */);
438
439 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700440}
441
Steven Moreland58a20c72018-10-09 12:30:51 -0700442static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
443 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800444 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700445 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800446 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700447 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800448 const Interface &iface = static_cast<const Interface &>(arg->type());
449 out << iface.getCppStackType() << " " << wrappedName << ";\n";
450 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
451 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
452 out << wrappedName
453 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700454 << "::android::hardware::details::wrapPassthrough("
455 << name
456 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800457 out.sIf(wrappedName + " == nullptr", [&] {
458 // Fatal error. Happens when the BsFoo class is not found in the binary
459 // or any dynamic libraries.
460 handleError();
461 }).endl();
462 }).sElse([&] {
463 out << wrappedName << " = " << name << ";\n";
464 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700465
466 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800467}
468
Steven Moreland616cf4d2018-10-02 13:52:18 -0700469void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700470 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700471
Steven Moreland58a20c72018-10-09 12:30:51 -0700472 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700473 out.indent();
474
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800475 if (method->isHidlReserved()
476 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
477 method->cppImpl(IMPL_PASSTHROUGH, out);
478 out.unindent();
479 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800480 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800481 }
482
Steven Moreland69e7c702016-09-09 11:16:32 -0700483 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700484 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700485
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700486 generateCppInstrumentationCall(
487 out,
488 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700489 method,
490 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700491
Steven Moreland58a20c72018-10-09 12:30:51 -0700492 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800493 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700494 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800495 out << "return ::android::hardware::Status::fromExceptionCode(\n";
496 out.indent(2, [&] {
497 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800498 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800499 });
500 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700501
502 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800503 }
504
Steven Moreland58a20c72018-10-09 12:30:51 -0700505 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700506 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700507
508 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700509 out << "addOnewayTask([mImpl = this->mImpl\n"
510 << "#ifdef __ANDROID_DEBUGGABLE__\n"
511 ", mEnableInstrumentation = this->mEnableInstrumentation, "
512 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
513 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700514 for (const std::string& arg : wrappedArgNames) {
515 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700516 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700517 out << "] {\n";
518 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700519 }
520
521 out << "mImpl->"
522 << method->name()
523 << "(";
524
Yifan Hong932464e2017-03-30 15:40:22 -0700525 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800526 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700527 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700528
529 std::function<void(void)> kHandlePassthroughError = [&] {
530 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
531 out.indent(2, [&] {
532 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
533 << "\"Cannot wrap passthrough interface.\");\n";
534 });
535 };
536
Steven Moreland69e7c702016-09-09 11:16:32 -0700537 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700538 // never true if oneway since oneway methods don't return values
539
Steven Moreland69e7c702016-09-09 11:16:32 -0700540 if (!method->args().empty()) {
541 out << ", ";
542 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800543 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700544 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800545 out << "const auto &_hidl_out_"
546 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700547 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800548
549 out << ") {\n";
550 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700551 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800552 out,
553 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700554 method,
555 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800556
Steven Moreland58a20c72018-10-09 12:30:51 -0700557 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800558 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700559 wrappedOutNames.push_back(
560 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800561 }
562
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800563 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700564 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
565 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800566 out << ");\n";
567 out.unindent();
568 out << "});\n\n";
569 } else {
570 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700571
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800572 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700573 const std::string outName = "_hidl_out_" + elidedReturn->name();
574
575 out << elidedReturn->type().getCppResultType() << " " << outName
576 << " = _hidl_return;\n";
577 out << "(void) " << outName << ";\n";
578
579 const std::string wrappedName =
580 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
581
582 if (outName != wrappedName) {
583 // update the original value since it is used by generateCppInstrumentationCall
584 out << outName << " = " << wrappedName << ";\n\n";
585
586 // update the value to be returned
587 out << "_hidl_return = " << outName << "\n;";
588 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800589 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700590 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800591 out,
592 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700593 method,
594 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700595 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700596
597 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700598 out.unindent();
599 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700600 } else {
601 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700602 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700603
604 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700605
606 out.unindent();
607 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700608}
609
Steven Moreland368e4602018-02-16 14:21:49 -0800610void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700611 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700612
Yifan Hong10fe0b52016-10-19 14:20:17 -0700613 const Interface *prevIterface = nullptr;
614 for (const auto &tuple : iface->allMethodsFromRoot()) {
615 const Method *method = tuple.method();
616 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700617
Steven Morelandf16c5c02017-07-31 16:50:06 -0700618 if (!includeParent && superInterface != iface) {
619 continue;
620 }
621
Yifan Hong10fe0b52016-10-19 14:20:17 -0700622 if(prevIterface != superInterface) {
623 if (prevIterface != nullptr) {
624 out << "\n";
625 }
626 out << "// Methods from "
627 << superInterface->fullName()
628 << " follow.\n";
629 prevIterface = superInterface;
630 }
Steven Moreland368e4602018-02-16 14:21:49 -0800631 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700632 }
633
Yifan Hong10fe0b52016-10-19 14:20:17 -0700634 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700635}
636
Steven Moreland0b843772017-06-23 16:33:38 -0700637void AST::generateTemplatizationLink(Formatter& out) const {
Neel Mehta291d02e2019-06-06 17:51:07 -0700638 DocComment("The pure class is what this class wraps.", HIDL_LOCATION_HERE).emit(out);
Neel Mehta257cce02019-07-19 13:24:57 -0700639 out << "typedef " << mRootScope.getInterface()->definedName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700640}
641
Steven Moreland1a52e822017-07-27 13:56:29 -0700642void AST::generateCppTag(Formatter& out, const std::string& tag) const {
643 out << "typedef " << tag << " _hidl_tag;\n\n";
644}
645
Steven Moreland368e4602018-02-16 14:21:49 -0800646void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800647 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700648
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700649 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800650 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700651 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700652
653 out << "#ifndef " << guard << "\n";
654 out << "#define " << guard << "\n\n";
655
Yifan Hongeefe4f22017-01-04 15:32:42 -0800656 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700657
Steven Morelandee88eed2016-10-31 17:49:00 -0700658 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700659
660 enterLeaveNamespace(out, true /* enter */);
661 out << "\n";
662
663 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800664 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100665 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800666 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000667 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100668 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800669 out << " : public "
670 << gIBaseFqName.getInterfaceStubFqName().cppName()
671 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100672 }
Andreas Huber881227d2016-08-02 14:20:21 -0700673
674 out.indent();
Neel Mehta257cce02019-07-19 13:24:57 -0700675 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
676 << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100677 << "\n";
Neel Mehta257cce02019-07-19 13:24:57 -0700678 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
679 << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800680 << " const std::string& HidlInstrumentor_package,"
681 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700682 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000683 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700684 out << "::android::status_t onTransact(\n";
685 out.indent();
686 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700687 out << "uint32_t _hidl_code,\n";
688 out << "const ::android::hardware::Parcel &_hidl_data,\n";
689 out << "::android::hardware::Parcel *_hidl_reply,\n";
690 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700691 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700692 out.unindent();
693 out.unindent();
694
Steven Moreland0b843772017-06-23 16:33:38 -0700695 out.endl();
696 generateTemplatizationLink(out);
Neel Mehta291d02e2019-06-06 17:51:07 -0700697 DocComment("Type tag for use in template logic that indicates this is a 'native' class.",
698 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700699 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700700 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700701
Neel Mehta257cce02019-07-19 13:24:57 -0700702 out << "::android::sp<" << iface->definedName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700703
Steven Moreland368e4602018-02-16 14:21:49 -0800704 generateMethods(out,
705 [&](const Method* method, const Interface*) {
706 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
707 return;
708 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700709
Steven Moreland368e4602018-02-16 14:21:49 -0800710 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700711
Steven Moreland368e4602018-02-16 14:21:49 -0800712 out.indent(2,
713 [&] {
714 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
715 << "const ::android::hardware::Parcel &_hidl_data,\n"
716 << "::android::hardware::Parcel *_hidl_reply,\n"
717 << "TransactCallback _hidl_cb);\n";
718 })
719 .endl()
720 .endl();
721 },
722 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700723
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100724 out.unindent();
725 out << "private:\n";
726 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800727
Steven Moreland368e4602018-02-16 14:21:49 -0800728 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800729 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800730 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800731 }
732 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700733 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800734
735 if (elidedReturn == nullptr && returnsValue) {
736 out << "using " << method->name() << "_cb = "
737 << iface->fqName().cppName()
738 << "::" << method->name() << "_cb;\n";
739 }
740 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800741 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800742 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800743
Neel Mehta257cce02019-07-19 13:24:57 -0700744 out << "::android::sp<" << iface->definedName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700745 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700746 out << "};\n\n";
747
748 enterLeaveNamespace(out, false /* enter */);
749
750 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700751}
752
Steven Moreland368e4602018-02-16 14:21:49 -0800753void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700754 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700755 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800756 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700757 }
758
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700759 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800760 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800761 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700762
763 out << "#ifndef " << guard << "\n";
764 out << "#define " << guard << "\n\n";
765
Martijn Coenen115d4282016-12-19 05:14:04 +0100766 out << "#include <hidl/HidlTransportSupport.h>\n\n";
767
Andreas Huber881227d2016-08-02 14:20:21 -0700768 std::vector<std::string> packageComponents;
769 getPackageAndVersionComponents(
770 &packageComponents, false /* cpp_compatible */);
771
Yifan Hongeefe4f22017-01-04 15:32:42 -0800772 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700773 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700774
775 enterLeaveNamespace(out, true /* enter */);
776 out << "\n";
777
Neel Mehta257cce02019-07-19 13:24:57 -0700778 out << "struct " << proxyName << " : public ::android::hardware::BpInterface<"
779 << iface->definedName() << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700780
781 out.indent();
782
Yifan Hongeefe4f22017-01-04 15:32:42 -0800783 out << "explicit "
784 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700785 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700786 << "\n\n";
787
Steven Moreland0b843772017-06-23 16:33:38 -0700788 generateTemplatizationLink(out);
Neel Mehta291d02e2019-06-06 17:51:07 -0700789 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.",
790 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700791 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700792 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700793
Yifan Hong10fe0b52016-10-19 14:20:17 -0700794 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700795
Steven Moreland596d20e2019-06-07 11:52:21 -0700796 out << "void onLastStrongRef(const void* id) override;\n\n";
797
Steven Moreland368e4602018-02-16 14:21:49 -0800798 generateMethods(
799 out,
800 [&](const Method* method, const Interface*) {
801 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
802 return;
803 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700804
Steven Moreland368e4602018-02-16 14:21:49 -0800805 out << "static ";
806 method->generateCppReturnType(out);
807 out << " _hidl_" << method->name() << "("
808 << "::android::hardware::IInterface* _hidl_this, "
809 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700810
Steven Moreland368e4602018-02-16 14:21:49 -0800811 if (!method->hasEmptyCppArgSignature()) {
812 out << ", ";
813 }
814 method->emitCppArgSignature(out);
815 out << ");\n";
816 },
817 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700818
Steven Moreland368e4602018-02-16 14:21:49 -0800819 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700820 method->generateCppSignature(out);
821 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700822 });
Steven Moreland9c387612016-09-07 09:54:26 -0700823
Andreas Huber881227d2016-08-02 14:20:21 -0700824 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100825 out << "private:\n";
826 out.indent();
827 out << "std::mutex _hidl_mMutex;\n"
828 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
829 << " _hidl_mDeathRecipients;\n";
830 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700831 out << "};\n\n";
832
833 enterLeaveNamespace(out, false /* enter */);
834
835 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700836}
837
Steven Moreland368e4602018-02-16 14:21:49 -0800838void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700839 std::string baseName = getBaseName();
840 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700841
Steven Morelanda885d252017-09-25 18:44:43 -0700842 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700843
Steven Moreland623c0042017-01-13 14:42:29 -0800844 out << "#define LOG_TAG \""
845 << mPackage.string() << "::" << baseName
846 << "\"\n\n";
847
Steven Moreland5add34d2018-11-08 16:31:30 -0800848 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100849 out << "#include <cutils/trace.h>\n";
850 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700851 out << "#include <hidl/Static.h>\n";
852 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700853 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700854 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700855 // This is a no-op for IServiceManager itself.
856 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
857
Yifan Hongeefe4f22017-01-04 15:32:42 -0800858 generateCppPackageInclude(out, mPackage, iface->getProxyName());
859 generateCppPackageInclude(out, mPackage, iface->getStubName());
860 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700861
862 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700863 generateCppPackageInclude(out,
864 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800865 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700866 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800867
868 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700869 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700870 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800871 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700872 }
873
874 out << "\n";
875
876 enterLeaveNamespace(out, true /* enter */);
877 out << "\n";
878
Neel Mehta257cce02019-07-19 13:24:57 -0700879 generateTypeSource(out, iface ? iface->definedName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700880
Steven Moreland368e4602018-02-16 14:21:49 -0800881 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700882 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700883
884 // need to be put here, generateStubSource is using this.
Neel Mehta257cce02019-07-19 13:24:57 -0700885 out << "const char* " << iface->definedName() << "::descriptor(\""
886 << iface->fqName().string() << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800887 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100888 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800889 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800890 out << "::android::hardware::details::getBnConstructorMap().set("
Neel Mehta257cce02019-07-19 13:24:57 -0700891 << iface->definedName() << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800892 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800893 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800894 out.indent([&] {
Neel Mehta257cce02019-07-19 13:24:57 -0700895 out << "return new " << iface->getStubName() << "(static_cast<"
896 << iface->definedName() << " *>(iIntf));\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800897 });
Yifan Hongb04de382017-02-06 15:31:52 -0800898 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800899 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800900 out << "::android::hardware::details::getBsConstructorMap().set("
Neel Mehta257cce02019-07-19 13:24:57 -0700901 << iface->definedName() << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800902 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800903 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800904 << gIBaseFqName.cppName()
905 << "> {\n";
906 out.indent([&] {
Neel Mehta257cce02019-07-19 13:24:57 -0700907 out << "return new " << iface->getPassthroughName() << "(static_cast<"
908 << iface->definedName() << " *>(iIntf));\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800909 });
Yifan Hongb04de382017-02-06 15:31:52 -0800910 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800911 });
Yifan Hong158655a2016-11-08 12:34:07 -0800912 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100913 out << "};\n\n";
914 out << "__attribute__((destructor))";
915 out << "static void static_destructor() {\n";
916 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800917 out << "::android::hardware::details::getBnConstructorMap().erase("
Neel Mehta257cce02019-07-19 13:24:57 -0700918 << iface->definedName() << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800919 out << "::android::hardware::details::getBsConstructorMap().erase("
Neel Mehta257cce02019-07-19 13:24:57 -0700920 << iface->definedName() << "::descriptor);\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100921 });
922 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800923
Steven Moreland368e4602018-02-16 14:21:49 -0800924 generateInterfaceSource(out);
925 generateProxySource(out, iface->fqName());
926 generateStubSource(out, iface);
927 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700928
Yifan Hongc8934042016-11-17 17:10:52 -0800929 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800930 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800931 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800932 std::string package = iface->fqName().package()
933 + iface->fqName().atVersion();
934
Yifan Hongeefe4f22017-01-04 15:32:42 -0800935 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800936 }
Steven Moreland40786312016-08-16 10:29:40 -0700937 }
938
Andreas Huber6755e9d2017-04-06 11:09:07 -0700939 HidlTypeAssertion::EmitAll(out);
940 out << "\n";
941
Andreas Huber881227d2016-08-02 14:20:21 -0700942 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700943}
944
Steven Moreland368e4602018-02-16 14:21:49 -0800945void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
946 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700947}
948
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700949void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
950 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700951 if (args.empty()) {
952 return;
953 }
954
955 for (const auto &arg : args) {
956 const Type &type = arg->type();
957
Yifan Hong3b320f82016-11-01 15:15:54 -0700958 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700959 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700960 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700961 << ";\n";
962 }
963
964 out << "\n";
965}
966
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700967void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
968 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
969 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700970 const Type &type = arg->type();
971
Andreas Huber881227d2016-08-02 14:20:21 -0700972 type.emitReaderWriter(
973 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700974 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700975 parcelObj,
976 parcelObjIsPointer,
977 isReader,
978 mode);
979}
980
Steven Moreland368e4602018-02-16 14:21:49 -0800981void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
982 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700983 method->generateCppSignature(out,
984 klassName,
985 true /* specify namespaces */);
986
Martijn Coenen115d4282016-12-19 05:14:04 +0100987 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -0700988 out.block([&] {
989 method->cppImpl(IMPL_PROXY, out);
990 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -0800991 return;
Martijn Coenen115d4282016-12-19 05:14:04 +0100992 }
993
Steven Morelandf16c5c02017-07-31 16:50:06 -0700994 out.block([&] {
995 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700996 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -0700997
998 method->generateCppReturnType(out);
999
1000 out << " _hidl_out = "
1001 << superInterface->fqName().cppNamespace()
1002 << "::"
1003 << superInterface->getProxyName()
1004 << "::_hidl_"
1005 << method->name()
1006 << "(this, this";
1007
1008 if (!method->hasEmptyCppArgSignature()) {
1009 out << ", ";
1010 }
1011
1012 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1013 out << arg->name();
1014 });
1015
1016 if (returnsValue && elidedReturn == nullptr) {
1017 if (!method->args().empty()) {
1018 out << ", ";
1019 }
1020 out << "_hidl_cb";
1021 }
1022
1023 out << ");\n\n";
1024
1025 out << "return _hidl_out;\n";
1026 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001027}
1028
Steven Moreland368e4602018-02-16 14:21:49 -08001029void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001030 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001031 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001032 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001033 }
1034
1035 method->generateCppReturnType(out);
1036
1037 out << klassName
1038 << "::_hidl_"
1039 << method->name()
1040 << "("
1041 << "::android::hardware::IInterface *_hidl_this, "
1042 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1043
1044 if (!method->hasEmptyCppArgSignature()) {
1045 out << ", ";
1046 }
1047
1048 method->emitCppArgSignature(out);
1049 out << ") {\n";
1050
1051 out.indent();
1052
1053 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1054 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1055 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1056 out << "#else\n";
1057 out << "(void) _hidl_this_instrumentor;\n";
1058 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1059
1060 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001061 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001062 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1063
Steven Moreland92a08a72017-07-31 14:57:37 -07001064 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001065 out,
1066 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001067 method,
1068 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001069
1070 out << "::android::hardware::Parcel _hidl_data;\n";
1071 out << "::android::hardware::Parcel _hidl_reply;\n";
1072 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001073 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001074 out << "::android::hardware::Status _hidl_status;\n\n";
1075
Steven Moreland48cc6042019-04-30 11:28:56 -07001076 if (!hasCallback) {
1077 declareCppReaderLocals(
1078 out, method->results(), true /* forResults */);
1079 }
Yifan Hong068c5522016-10-31 14:07:25 -07001080
1081 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001082 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001083 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001084 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1085
Martijn Coenenfff73352017-01-04 16:36:31 +01001086 bool hasInterfaceArgument = false;
Steven Moreland8249f0a2019-05-28 17:25:27 -07001087
Yifan Hong068c5522016-10-31 14:07:25 -07001088 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001089 if (arg->type().isInterface()) {
1090 hasInterfaceArgument = true;
1091 }
Yifan Hong068c5522016-10-31 14:07:25 -07001092 emitCppReaderWriter(
1093 out,
1094 "_hidl_data",
1095 false /* parcelObjIsPointer */,
1096 arg,
1097 false /* reader */,
1098 Type::ErrorMode_Goto,
1099 false /* addPrefixToName */);
1100 }
1101
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001102 if (hasInterfaceArgument) {
1103 // Start binder threadpool to handle incoming transactions
1104 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1105 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001106 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001107 << method->getSerialId()
1108 << " /* "
1109 << method->name()
1110 << " */, _hidl_data, &_hidl_reply";
1111
1112 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001113 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001114 } else {
1115 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001116 }
Yifan Hong068c5522016-10-31 14:07:25 -07001117
Steven Moreland48cc6042019-04-30 11:28:56 -07001118 if (hasCallback) {
1119 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1120 out.indent();
1121 declareCppReaderLocals(
1122 out, method->results(), true /* forResults */);
1123 out.endl();
1124 } else {
1125 out << ");\n";
1126 out << "if (_hidl_transact_err != ::android::OK) \n";
1127 out.block([&] {
1128 out << "_hidl_err = _hidl_transact_err;\n";
1129 out << "goto _hidl_error;\n";
1130 }).endl().endl();
1131 }
Yifan Hong068c5522016-10-31 14:07:25 -07001132
1133 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001134 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001135
Steven Moreland48cc6042019-04-30 11:28:56 -07001136 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1137 Type::handleError(out, errorMode);
1138
1139 if (hasCallback) {
1140 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1141 } else {
1142 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1143 }
Yifan Hong068c5522016-10-31 14:07:25 -07001144
Yifan Hong068c5522016-10-31 14:07:25 -07001145 for (const auto &arg : method->results()) {
1146 emitCppReaderWriter(
1147 out,
1148 "_hidl_reply",
1149 false /* parcelObjIsPointer */,
1150 arg,
1151 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001152 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001153 true /* addPrefixToName */);
1154 }
1155
Yifan Hong068c5522016-10-31 14:07:25 -07001156 if (returnsValue && elidedReturn == nullptr) {
1157 out << "_hidl_cb(";
1158
Yifan Hong932464e2017-03-30 15:40:22 -07001159 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001160 if (arg->type().resultNeedsDeref()) {
1161 out << "*";
1162 }
1163 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001164 });
Yifan Hong068c5522016-10-31 14:07:25 -07001165
1166 out << ");\n\n";
1167 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001168 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001169
Steven Moreland92a08a72017-07-31 14:57:37 -07001170 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001171 out,
1172 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001173 method,
1174 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001175
Steven Moreland48cc6042019-04-30 11:28:56 -07001176 if (hasCallback) {
1177 out.unindent();
1178 out << "});\n";
1179 out << "if (_hidl_transact_err != ::android::OK) ";
1180 out.block([&] {
1181 out << "_hidl_err = _hidl_transact_err;\n";
1182 out << "goto _hidl_error;\n";
1183 }).endl().endl();
1184 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1185 }
1186
Yifan Hong068c5522016-10-31 14:07:25 -07001187 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001188 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001189 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001190 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1191 } else {
Yifan Hong068c5522016-10-31 14:07:25 -07001192 out << "return ::android::hardware::Return<void>();\n\n";
1193 }
1194
1195 out.unindent();
1196 out << "_hidl_error:\n";
1197 out.indent();
1198 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1199 out << "return ::android::hardware::Return<";
1200 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001201 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001202 } else {
1203 out << "void";
1204 }
1205 out << ">(_hidl_status);\n";
1206
1207 out.unindent();
1208 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001209}
1210
Steven Moreland368e4602018-02-16 14:21:49 -08001211void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001212 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001213
1214 out << klassName
1215 << "::"
1216 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001217 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001218
1219 out.indent();
1220 out.indent();
1221
1222 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001223 << "<"
1224 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001225 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001226 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001227 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001228 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001229 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001230 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001231
Andreas Huber881227d2016-08-02 14:20:21 -07001232 out.unindent();
1233 out.unindent();
1234 out << "}\n\n";
1235
Steven Moreland596d20e2019-06-07 11:52:21 -07001236 out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1237 out.block([&] {
1238 out.block([&] {
1239 // if unlinkToDeath is not used, remove strong cycle between
1240 // this and hidl_binder_death_recipient
1241 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1242 out << "_hidl_mDeathRecipients.clear();\n";
1243 }).endl().endl();
1244
1245 out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1246 }).endl();
1247
Steven Moreland368e4602018-02-16 14:21:49 -08001248 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001249 [&](const Method* method, const Interface* superInterface) {
1250 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001251 },
1252 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001253
Steven Moreland368e4602018-02-16 14:21:49 -08001254 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1255 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001256 });
Andreas Huber881227d2016-08-02 14:20:21 -07001257}
1258
Steven Moreland368e4602018-02-16 14:21:49 -08001259void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Neel Mehta257cce02019-07-19 13:24:57 -07001260 const std::string interfaceName = iface->definedName();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001261 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001262
Steven Moreland40786312016-08-16 10:29:40 -07001263 out << klassName
1264 << "::"
1265 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001266 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001267
1268 out.indent();
1269 out.indent();
1270
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001271 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001272 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001273 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001274 out << ": "
1275 << gIBaseFqName.getInterfaceStubFqName().cppName()
1276 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001277 }
1278
1279 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001280 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001281 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001282 << "\") { \n";
1283 out.indent();
1284 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001285 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001286 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1287 out << "mSchedPolicy = prio.sched_policy;\n";
1288 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001289 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1290 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001291 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001292
1293 out.unindent();
1294 out.unindent();
1295 out << "}\n\n";
1296
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001297 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001298 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001299 // class properly.
1300 out << klassName
1301 << "::"
1302 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001303 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1304 << " const std::string &HidlInstrumentor_package,"
1305 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001306
1307 out.indent();
1308 out.indent();
1309
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001310 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001311 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001312 out.indent();
1313 out << "_hidl_mImpl = _hidl_impl;\n";
1314 out.unindent();
1315
1316 out.unindent();
1317 out.unindent();
1318 out << "}\n\n";
1319 }
1320
Steven Moreland57a89362017-07-21 19:29:54 +00001321 out << klassName << "::~" << klassName << "() ";
1322 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001323 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1324 })
1325 .endl()
1326 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001327
Steven Moreland368e4602018-02-16 14:21:49 -08001328 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001329 [&](const Method* method, const Interface* superInterface) {
1330 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001331 },
1332 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001333
Steven Moreland368e4602018-02-16 14:21:49 -08001334 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001335 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001336 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001337 }
1338 method->generateCppSignature(out, iface->getStubName());
1339 out << " ";
1340 out.block([&] {
1341 method->cppImpl(IMPL_STUB_IMPL, out);
1342 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001343 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001344
Andreas Huber881227d2016-08-02 14:20:21 -07001345 out << "::android::status_t " << klassName << "::onTransact(\n";
1346
1347 out.indent();
1348 out.indent();
1349
Iliyan Malchev549e2592016-08-10 08:59:12 -07001350 out << "uint32_t _hidl_code,\n"
1351 << "const ::android::hardware::Parcel &_hidl_data,\n"
1352 << "::android::hardware::Parcel *_hidl_reply,\n"
1353 << "uint32_t _hidl_flags,\n"
1354 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001355
1356 out.unindent();
1357
Iliyan Malchev549e2592016-08-10 08:59:12 -07001358 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001359 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001360 out.indent();
1361
Yifan Hong10fe0b52016-10-19 14:20:17 -07001362 for (const auto &tuple : iface->allMethodsFromRoot()) {
1363 const Method *method = tuple.method();
1364 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001365
Howard Chen71f289f2017-08-29 17:35:01 +08001366 if (!isIBase() && method->isHidlReserved()) {
1367 continue;
1368 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001369 out << "case "
1370 << method->getSerialId()
1371 << " /* "
1372 << method->name()
1373 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001374
Yifan Hong10fe0b52016-10-19 14:20:17 -07001375 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001376
Steven Moreland368e4602018-02-16 14:21:49 -08001377 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001378
1379 out.unindent();
1380 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001381 }
1382
1383 out << "default:\n{\n";
1384 out.indent();
1385
Martijn Coenen225bc922017-06-27 14:39:46 -07001386 if (iface->isIBase()) {
1387 out << "(void)_hidl_flags;\n";
1388 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1389 } else {
1390 out << "return ";
1391 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1392 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001393
Martijn Coenen225bc922017-06-27 14:39:46 -07001394 out.indent();
1395 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001396
Martijn Coenen225bc922017-06-27 14:39:46 -07001397 out << "_hidl_code, _hidl_data, _hidl_reply, "
1398 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001399
Martijn Coenen225bc922017-06-27 14:39:46 -07001400 out.unindent();
1401 out.unindent();
1402 }
Andreas Huber881227d2016-08-02 14:20:21 -07001403
1404 out.unindent();
1405 out << "}\n";
1406
1407 out.unindent();
1408 out << "}\n\n";
1409
Yifan Honga018ed52016-12-13 16:35:08 -08001410 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1411 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1412 out.indent(2, [&] {
1413 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1414 out << "_hidl_reply);\n";
1415 });
1416 });
Andreas Huber881227d2016-08-02 14:20:21 -07001417
Iliyan Malchev549e2592016-08-10 08:59:12 -07001418 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001419
1420 out.unindent();
1421 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001422}
1423
Steven Moreland368e4602018-02-16 14:21:49 -08001424void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1425 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001426 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1427 method->cppImpl(IMPL_STUB, out);
1428 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001429 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001430 }
1431
Steven Morelandf16c5c02017-07-31 16:50:06 -07001432 out << "_hidl_err = "
1433 << superInterface->fqName().cppNamespace()
1434 << "::"
1435 << superInterface->getStubName()
1436 << "::_hidl_"
1437 << method->name()
1438 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1439 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001440}
1441
Steven Moreland368e4602018-02-16 14:21:49 -08001442void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001443 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001444 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001445 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001446 }
1447
Steven Morelandf8197902018-01-30 15:38:37 -08001448 const std::string& klassName = fqName.getInterfaceStubName();
1449
Steven Morelandf16c5c02017-07-31 16:50:06 -07001450 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1451
1452 out.indent();
1453 out.indent();
1454
1455 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1456 << "const ::android::hardware::Parcel &_hidl_data,\n"
1457 << "::android::hardware::Parcel *_hidl_reply,\n"
1458 << "TransactCallback _hidl_cb) {\n";
1459
1460 out.unindent();
1461
1462 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1463 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1464 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1465 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1466
1467 out << "::android::status_t _hidl_err = ::android::OK;\n";
1468
Yifan Hongeefe4f22017-01-04 15:32:42 -08001469 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001470 << klassName
1471 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001472
Andreas Huber881227d2016-08-02 14:20:21 -07001473 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001474 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001475 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001476 out.unindent();
1477 out << "}\n\n";
1478
Andreas Huber5e44a292016-09-27 14:52:39 -07001479 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001480
Andreas Huber881227d2016-08-02 14:20:21 -07001481 for (const auto &arg : method->args()) {
1482 emitCppReaderWriter(
1483 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001484 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001485 false /* parcelObjIsPointer */,
1486 arg,
1487 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001488 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001489 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001490 }
1491
Steven Moreland92a08a72017-07-31 14:57:37 -07001492 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001493 out,
1494 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001495 method,
1496 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001497
Andreas Huber881227d2016-08-02 14:20:21 -07001498 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001499 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001500
1501 std::string callee;
1502
1503 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1504 callee = "_hidl_this";
1505 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001506 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001507 }
Andreas Huber881227d2016-08-02 14:20:21 -07001508
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001509 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001510 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001511 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001512 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001513 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001514 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001515 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001516
Yifan Hong932464e2017-03-30 15:40:22 -07001517 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001518 if (arg->type().resultNeedsDeref()) {
1519 out << "*";
1520 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001521 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001522 });
Andreas Huber881227d2016-08-02 14:20:21 -07001523
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001524 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001525
Yifan Hong859e53f2016-11-14 19:08:24 -08001526 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1527 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001528
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001529 elidedReturn->type().emitReaderWriter(
1530 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001531 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001532 "_hidl_reply",
1533 true, /* parcelObjIsPointer */
1534 false, /* isReader */
1535 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001536
Steven Moreland92a08a72017-07-31 14:57:37 -07001537 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001538 out,
1539 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001540 method,
1541 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001542
Iliyan Malchev549e2592016-08-10 08:59:12 -07001543 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001544 } else {
1545 if (returnsValue) {
1546 out << "bool _hidl_callbackCalled = false;\n\n";
1547 }
Andreas Huber881227d2016-08-02 14:20:21 -07001548
Steven Moreland30232dc2019-03-05 19:39:10 -08001549 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1550 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001551
Yifan Hong932464e2017-03-30 15:40:22 -07001552 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001553 if (arg->type().resultNeedsDeref()) {
1554 out << "*";
1555 }
1556
1557 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001558 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001559
1560 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001561 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001562 out << ", ";
1563 }
1564
1565 out << "[&](";
1566
Yifan Hong932464e2017-03-30 15:40:22 -07001567 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001568 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001569 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001570
1571 out << ") {\n";
1572 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001573 out << "if (_hidl_callbackCalled) {\n";
1574 out.indent();
1575 out << "LOG_ALWAYS_FATAL(\""
1576 << method->name()
1577 << ": _hidl_cb called a second time, but must be called once.\");\n";
1578 out.unindent();
1579 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001580 out << "_hidl_callbackCalled = true;\n\n";
1581
Yifan Hong859e53f2016-11-14 19:08:24 -08001582 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1583 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001584
1585 for (const auto &arg : method->results()) {
1586 emitCppReaderWriter(
1587 out,
1588 "_hidl_reply",
1589 true /* parcelObjIsPointer */,
1590 arg,
1591 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001592 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001593 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001594 }
1595
Steven Moreland92a08a72017-07-31 14:57:37 -07001596 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001597 out,
1598 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001599 method,
1600 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001601
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001602 out << "_hidl_cb(*_hidl_reply);\n";
1603
1604 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001605 out << "});\n\n";
1606 } else {
1607 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001608 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001609 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001610 out,
1611 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001612 method,
1613 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001614 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001615
Steven Moreland30232dc2019-03-05 19:39:10 -08001616 out << "_hidl_ret.assertOk();\n";
1617
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001618 if (returnsValue) {
1619 out << "if (!_hidl_callbackCalled) {\n";
1620 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001621 out << "LOG_ALWAYS_FATAL(\""
1622 << method->name()
1623 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001624 out.unindent();
1625 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001626 } else {
1627 out << "::android::hardware::writeToParcel("
1628 << "::android::hardware::Status::ok(), "
1629 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001630 }
Andreas Huber881227d2016-08-02 14:20:21 -07001631 }
1632
Steven Morelandf16c5c02017-07-31 16:50:06 -07001633 out << "return _hidl_err;\n";
1634 out.unindent();
1635 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001636}
1637
Steven Moreland368e4602018-02-16 14:21:49 -08001638void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001639 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001640 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001641 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001642 }
1643
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001644 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001645 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001646
Yifan Hongeefe4f22017-01-04 15:32:42 -08001647 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001648
Steven Moreland69e7c702016-09-09 11:16:32 -07001649 const std::string guard = makeHeaderGuard(klassName);
1650
1651 out << "#ifndef " << guard << "\n";
1652 out << "#define " << guard << "\n\n";
1653
1654 std::vector<std::string> packageComponents;
1655 getPackageAndVersionComponents(
1656 &packageComponents, false /* cpp_compatible */);
1657
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001658 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001659 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001660 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001661
Neel Mehta257cce02019-07-19 13:24:57 -07001662 generateCppPackageInclude(out, mPackage, iface->definedName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001663 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001664
Yifan Hong7a118f52016-12-07 11:21:15 -08001665 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001666 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001667
1668 enterLeaveNamespace(out, true /* enter */);
1669 out << "\n";
1670
Neel Mehta257cce02019-07-19 13:24:57 -07001671 out << "struct " << klassName << " : " << iface->definedName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001672 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001673
1674 out.indent();
Neel Mehta257cce02019-07-19 13:24:57 -07001675 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001676 << "> impl);\n";
1677
Steven Moreland0b843772017-06-23 16:33:38 -07001678 out.endl();
1679 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001680 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001681
Steven Moreland616cf4d2018-10-02 13:52:18 -07001682 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1683 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001684 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001685
Steven Moreland69e7c702016-09-09 11:16:32 -07001686 out.unindent();
1687 out << "private:\n";
1688 out.indent();
Neel Mehta257cce02019-07-19 13:24:57 -07001689 out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001690
Neel Mehta19f79792019-05-21 13:39:32 -07001691 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001692
Neel Mehta19f79792019-05-21 13:39:32 -07001693 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001694
Neel Mehta19f79792019-05-21 13:39:32 -07001695 out << "::android::hardware::Return<void> addOnewayTask("
1696 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001697
1698 out.unindent();
1699
1700 out << "};\n\n";
1701
1702 enterLeaveNamespace(out, false /* enter */);
1703
1704 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001705}
1706
Steven Moreland368e4602018-02-16 14:21:49 -08001707void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001708 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001709
Yifan Hong2d7126b2016-10-20 15:12:57 -07001710 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001711 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001712
Steven Moreland368e4602018-02-16 14:21:49 -08001713 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001714 bool reserved = method->isHidlReserved();
1715
1716 if (!reserved) {
1717 out << "// no default implementation for: ";
1718 }
Neel Mehta257cce02019-07-19 13:24:57 -07001719 method->generateCppSignature(out, iface->definedName());
Steven Morelandd4b068a2017-03-20 06:30:51 -07001720 if (reserved) {
1721 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001722 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001723 }).endl();
1724 }
1725
1726 out << "\n";
1727
Steven Moreland368e4602018-02-16 14:21:49 -08001728 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001729 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001730
Yifan Hong3d746092016-12-07 14:26:33 -08001731 for (const Interface *superType : iface->typeChain()) {
Neel Mehta257cce02019-07-19 13:24:57 -07001732 out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1733 << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1734 << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001735 out.indent();
1736 if (iface == superType) {
1737 out << "return parent;\n";
1738 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001739 out << "return ::android::hardware::details::castInterface<";
Neel Mehta257cce02019-07-19 13:24:57 -07001740 out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1741 << iface->getProxyName() << ">(\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001742 out.indent();
1743 out.indent();
1744 out << "parent, \""
1745 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001746 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001747 out.unindent();
1748 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001749 }
Yifan Hong3d746092016-12-07 14:26:33 -08001750 out.unindent();
1751 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001752 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001753}
1754
Steven Moreland368e4602018-02-16 14:21:49 -08001755void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001756 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001757
Yifan Hongeefe4f22017-01-04 15:32:42 -08001758 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001759
Neel Mehta19f79792019-05-21 13:39:32 -07001760 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1761 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
Neel Mehta257cce02019-07-19 13:24:57 -07001762 << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001763
1764 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1765
Yifan Hong2cbc1472016-10-25 19:02:40 -07001766 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001767
Neel Mehta19f79792019-05-21 13:39:32 -07001768 out << "::android::hardware::Return<void> " << klassName
1769 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1770 out.indent();
1771 out << "if (!mOnewayQueue.push(fun)) {\n";
1772 out.indent();
1773 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1774 out.indent();
1775 out.indent();
1776 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1777 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1778 out.unindent();
1779 out.unindent();
1780 out.unindent();
1781 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001782
Neel Mehta19f79792019-05-21 13:39:32 -07001783 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001784
Neel Mehta19f79792019-05-21 13:39:32 -07001785 out.unindent();
1786 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001787}
1788
Steven Moreland92a08a72017-07-31 14:57:37 -07001789void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001790 InstrumentationEvent event,
1791 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001792 const Interface* iface = mRootScope.getInterface();
Neel Mehta257cce02019-07-19 13:24:57 -07001793 std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001794 switch (event) {
1795 case SERVER_API_ENTRY:
1796 {
1797 out << "atrace_begin(ATRACE_TAG_HAL, \""
1798 << baseString + "::server\");\n";
1799 break;
1800 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001801 case PASSTHROUGH_ENTRY:
1802 {
1803 out << "atrace_begin(ATRACE_TAG_HAL, \""
1804 << baseString + "::passthrough\");\n";
1805 break;
1806 }
1807 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001808 case PASSTHROUGH_EXIT:
1809 {
1810 out << "atrace_end(ATRACE_TAG_HAL);\n";
1811 break;
1812 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001813 // client uses scope because of gotos
1814 // this isn't done for server because the profiled code isn't alone in its scope
1815 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1816 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001817 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1818 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001819 break;
1820 }
1821 case CLIENT_API_EXIT:
1822 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001823 default:
1824 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001825 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001826 }
1827 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001828}
1829
Steven Moreland92a08a72017-07-31 14:57:37 -07001830void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001831 Formatter &out,
1832 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001833 const Method *method,
1834 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001835 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001836
Steven Moreland30b76e92017-06-02 18:52:24 -07001837 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001838 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1839 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001840 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001841 std::string event_str = "";
1842 switch (event) {
1843 case SERVER_API_ENTRY:
1844 {
1845 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1846 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001847 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001848 << (arg->type().resultNeedsDeref() ? "" : "&")
1849 << arg->name()
1850 << ");\n";
1851 }
1852 break;
1853 }
1854 case SERVER_API_EXIT:
1855 {
1856 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001857 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001858 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001859 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001860 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001861 }
1862 break;
1863 }
1864 case CLIENT_API_ENTRY:
1865 {
1866 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1867 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001868 out << "_hidl_args.push_back((void *)&"
1869 << arg->name()
1870 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001871 }
1872 break;
1873 }
1874 case CLIENT_API_EXIT:
1875 {
1876 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1877 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001878 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001879 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001880 << "_hidl_out_"
1881 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001882 << ");\n";
1883 }
1884 break;
1885 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001886 case PASSTHROUGH_ENTRY:
1887 {
1888 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1889 for (const auto &arg : method->args()) {
1890 out << "_hidl_args.push_back((void *)&"
1891 << arg->name()
1892 << ");\n";
1893 }
1894 break;
1895 }
1896 case PASSTHROUGH_EXIT:
1897 {
1898 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001899 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001900 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001901 << arg->name()
1902 << ");\n";
1903 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001904 break;
1905 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001906 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001907 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001908 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001909 }
1910 }
1911
Steven Moreland1ab31442016-11-03 18:37:51 -07001912 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001913 out.indent();
Neel Mehta257cce02019-07-19 13:24:57 -07001914 out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1915 << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1916 << "\", \"" << method->name() << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001917 out.unindent();
1918 out << "}\n";
1919 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001920 out << "}\n";
1921 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001922}
1923
Andreas Huber881227d2016-08-02 14:20:21 -07001924} // namespace android