blob: ba12300de283f2be9bb7e1f7333382094b123f95 [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 Mehta9200af02019-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);
Diogo Ferreira604fe012019-10-17 12:32:00 +0100288 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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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);
Diogo Ferreira604fe012019-10-17 12:32:00 +0100700 generateCppTag(out, "::android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700701
Neel Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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);
Diogo Ferreira604fe012019-10-17 12:32:00 +0100792 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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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 Mehta9200af02019-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 });
Bernhard Rosenkränzera8be3492018-04-15 22:32:41 +0200913 out << "}\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100914 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 Mehta9200af02019-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 Mehta9200af02019-07-19 13:24:57 -0700920 << iface->definedName() << "::descriptor);\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100921 });
Bernhard Rosenkränzera8be3492018-04-15 22:32:41 +0200922 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 Mehta9200af02019-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 Moreland0e0935c2019-09-18 12:05:36 -07001285 out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
Martijn Coenenb4d77952017-05-03 13:44:29 -07001286 out << "mSchedPolicy = prio.sched_policy;\n";
1287 out << "mSchedPriority = prio.prio;\n";
Steven Moreland0e0935c2019-09-18 12:05:36 -07001288 out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001289 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001290
1291 out.unindent();
1292 out.unindent();
1293 out << "}\n\n";
1294
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001295 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001296 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001297 // class properly.
1298 out << klassName
1299 << "::"
1300 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001301 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1302 << " const std::string &HidlInstrumentor_package,"
1303 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001304
1305 out.indent();
1306 out.indent();
1307
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001308 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001309 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001310 out.indent();
1311 out << "_hidl_mImpl = _hidl_impl;\n";
1312 out.unindent();
1313
1314 out.unindent();
1315 out.unindent();
1316 out << "}\n\n";
1317 }
1318
Steven Moreland57a89362017-07-21 19:29:54 +00001319 out << klassName << "::~" << klassName << "() ";
1320 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001321 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1322 })
1323 .endl()
1324 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001325
Steven Moreland368e4602018-02-16 14:21:49 -08001326 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001327 [&](const Method* method, const Interface* superInterface) {
1328 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001329 },
1330 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001331
Steven Moreland368e4602018-02-16 14:21:49 -08001332 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001333 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001334 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001335 }
1336 method->generateCppSignature(out, iface->getStubName());
1337 out << " ";
1338 out.block([&] {
1339 method->cppImpl(IMPL_STUB_IMPL, out);
1340 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001341 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001342
Andreas Huber881227d2016-08-02 14:20:21 -07001343 out << "::android::status_t " << klassName << "::onTransact(\n";
1344
1345 out.indent();
1346 out.indent();
1347
Iliyan Malchev549e2592016-08-10 08:59:12 -07001348 out << "uint32_t _hidl_code,\n"
1349 << "const ::android::hardware::Parcel &_hidl_data,\n"
1350 << "::android::hardware::Parcel *_hidl_reply,\n"
1351 << "uint32_t _hidl_flags,\n"
1352 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001353
1354 out.unindent();
1355
Iliyan Malchev549e2592016-08-10 08:59:12 -07001356 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001357 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001358 out.indent();
1359
Yifan Hong10fe0b52016-10-19 14:20:17 -07001360 for (const auto &tuple : iface->allMethodsFromRoot()) {
1361 const Method *method = tuple.method();
1362 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001363
Howard Chen71f289f2017-08-29 17:35:01 +08001364 if (!isIBase() && method->isHidlReserved()) {
1365 continue;
1366 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001367 out << "case "
1368 << method->getSerialId()
1369 << " /* "
1370 << method->name()
1371 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001372
Yifan Hong10fe0b52016-10-19 14:20:17 -07001373 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001374
Steven Moreland368e4602018-02-16 14:21:49 -08001375 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001376
1377 out.unindent();
1378 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001379 }
1380
1381 out << "default:\n{\n";
1382 out.indent();
1383
Martijn Coenen225bc922017-06-27 14:39:46 -07001384 if (iface->isIBase()) {
1385 out << "(void)_hidl_flags;\n";
1386 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1387 } else {
1388 out << "return ";
1389 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1390 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001391
Martijn Coenen225bc922017-06-27 14:39:46 -07001392 out.indent();
1393 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001394
Martijn Coenen225bc922017-06-27 14:39:46 -07001395 out << "_hidl_code, _hidl_data, _hidl_reply, "
1396 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001397
Martijn Coenen225bc922017-06-27 14:39:46 -07001398 out.unindent();
1399 out.unindent();
1400 }
Andreas Huber881227d2016-08-02 14:20:21 -07001401
1402 out.unindent();
1403 out << "}\n";
1404
1405 out.unindent();
1406 out << "}\n\n";
1407
Yifan Honga018ed52016-12-13 16:35:08 -08001408 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1409 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1410 out.indent(2, [&] {
1411 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1412 out << "_hidl_reply);\n";
1413 });
1414 });
Andreas Huber881227d2016-08-02 14:20:21 -07001415
Iliyan Malchev549e2592016-08-10 08:59:12 -07001416 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001417
1418 out.unindent();
1419 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001420}
1421
Steven Moreland368e4602018-02-16 14:21:49 -08001422void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1423 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001424 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1425 method->cppImpl(IMPL_STUB, out);
1426 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001427 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001428 }
1429
Steven Morelandf16c5c02017-07-31 16:50:06 -07001430 out << "_hidl_err = "
1431 << superInterface->fqName().cppNamespace()
1432 << "::"
1433 << superInterface->getStubName()
1434 << "::_hidl_"
1435 << method->name()
1436 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1437 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001438}
1439
Steven Moreland368e4602018-02-16 14:21:49 -08001440void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001441 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001442 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001443 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001444 }
1445
Steven Morelandf8197902018-01-30 15:38:37 -08001446 const std::string& klassName = fqName.getInterfaceStubName();
1447
Steven Morelandf16c5c02017-07-31 16:50:06 -07001448 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1449
1450 out.indent();
1451 out.indent();
1452
1453 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1454 << "const ::android::hardware::Parcel &_hidl_data,\n"
1455 << "::android::hardware::Parcel *_hidl_reply,\n"
1456 << "TransactCallback _hidl_cb) {\n";
1457
1458 out.unindent();
1459
1460 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1461 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1462 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1463 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1464
1465 out << "::android::status_t _hidl_err = ::android::OK;\n";
1466
Yifan Hongeefe4f22017-01-04 15:32:42 -08001467 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001468 << klassName
1469 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001470
Andreas Huber881227d2016-08-02 14:20:21 -07001471 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001472 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001473 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001474 out.unindent();
1475 out << "}\n\n";
1476
Andreas Huber5e44a292016-09-27 14:52:39 -07001477 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001478
Andreas Huber881227d2016-08-02 14:20:21 -07001479 for (const auto &arg : method->args()) {
1480 emitCppReaderWriter(
1481 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001482 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001483 false /* parcelObjIsPointer */,
1484 arg,
1485 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001486 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001487 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001488 }
1489
Steven Moreland92a08a72017-07-31 14:57:37 -07001490 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001491 out,
1492 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001493 method,
1494 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001495
Andreas Huber881227d2016-08-02 14:20:21 -07001496 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001497 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001498
1499 std::string callee;
1500
1501 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1502 callee = "_hidl_this";
1503 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001504 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001505 }
Andreas Huber881227d2016-08-02 14:20:21 -07001506
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001507 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001508 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001509 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001510 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001511 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001512 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001513 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001514
Yifan Hong932464e2017-03-30 15:40:22 -07001515 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001516 if (arg->type().resultNeedsDeref()) {
1517 out << "*";
1518 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001519 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001520 });
Andreas Huber881227d2016-08-02 14:20:21 -07001521
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001522 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001523
Yifan Hong859e53f2016-11-14 19:08:24 -08001524 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1525 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001526
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001527 elidedReturn->type().emitReaderWriter(
1528 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001529 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001530 "_hidl_reply",
1531 true, /* parcelObjIsPointer */
1532 false, /* isReader */
1533 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001534
Steven Moreland92a08a72017-07-31 14:57:37 -07001535 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001536 out,
1537 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001538 method,
1539 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001540
Iliyan Malchev549e2592016-08-10 08:59:12 -07001541 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001542 } else {
1543 if (returnsValue) {
1544 out << "bool _hidl_callbackCalled = false;\n\n";
1545 }
Andreas Huber881227d2016-08-02 14:20:21 -07001546
Steven Moreland30232dc2019-03-05 19:39:10 -08001547 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1548 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001549
Yifan Hong932464e2017-03-30 15:40:22 -07001550 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001551 if (arg->type().resultNeedsDeref()) {
1552 out << "*";
1553 }
1554
1555 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001556 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001557
1558 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001559 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001560 out << ", ";
1561 }
1562
1563 out << "[&](";
1564
Yifan Hong932464e2017-03-30 15:40:22 -07001565 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001566 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001567 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001568
1569 out << ") {\n";
1570 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001571 out << "if (_hidl_callbackCalled) {\n";
1572 out.indent();
1573 out << "LOG_ALWAYS_FATAL(\""
1574 << method->name()
1575 << ": _hidl_cb called a second time, but must be called once.\");\n";
1576 out.unindent();
1577 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001578 out << "_hidl_callbackCalled = true;\n\n";
1579
Yifan Hong859e53f2016-11-14 19:08:24 -08001580 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1581 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001582
1583 for (const auto &arg : method->results()) {
1584 emitCppReaderWriter(
1585 out,
1586 "_hidl_reply",
1587 true /* parcelObjIsPointer */,
1588 arg,
1589 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001590 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001591 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001592 }
1593
Steven Moreland92a08a72017-07-31 14:57:37 -07001594 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001595 out,
1596 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001597 method,
1598 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001599
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001600 out << "_hidl_cb(*_hidl_reply);\n";
1601
1602 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001603 out << "});\n\n";
1604 } else {
1605 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001606 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001607 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001608 out,
1609 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001610 method,
1611 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001612 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001613
Steven Moreland30232dc2019-03-05 19:39:10 -08001614 out << "_hidl_ret.assertOk();\n";
1615
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001616 if (returnsValue) {
1617 out << "if (!_hidl_callbackCalled) {\n";
1618 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001619 out << "LOG_ALWAYS_FATAL(\""
1620 << method->name()
1621 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001622 out.unindent();
1623 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001624 } else {
1625 out << "::android::hardware::writeToParcel("
1626 << "::android::hardware::Status::ok(), "
1627 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 }
Andreas Huber881227d2016-08-02 14:20:21 -07001629 }
1630
Steven Morelandf16c5c02017-07-31 16:50:06 -07001631 out << "return _hidl_err;\n";
1632 out.unindent();
1633 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001634}
1635
Steven Moreland368e4602018-02-16 14:21:49 -08001636void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001637 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001638 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001639 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001640 }
1641
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001642 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001643 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001644
Yifan Hongeefe4f22017-01-04 15:32:42 -08001645 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001646
Steven Moreland69e7c702016-09-09 11:16:32 -07001647 const std::string guard = makeHeaderGuard(klassName);
1648
1649 out << "#ifndef " << guard << "\n";
1650 out << "#define " << guard << "\n\n";
1651
1652 std::vector<std::string> packageComponents;
1653 getPackageAndVersionComponents(
1654 &packageComponents, false /* cpp_compatible */);
1655
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001656 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001657 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001658 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001659
Neel Mehta9200af02019-07-19 13:24:57 -07001660 generateCppPackageInclude(out, mPackage, iface->definedName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001661 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001662
Yifan Hong7a118f52016-12-07 11:21:15 -08001663 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001664 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001665
1666 enterLeaveNamespace(out, true /* enter */);
1667 out << "\n";
1668
Neel Mehta9200af02019-07-19 13:24:57 -07001669 out << "struct " << klassName << " : " << iface->definedName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001670 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001671
1672 out.indent();
Neel Mehta9200af02019-07-19 13:24:57 -07001673 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001674 << "> impl);\n";
1675
Steven Moreland0b843772017-06-23 16:33:38 -07001676 out.endl();
1677 generateTemplatizationLink(out);
Diogo Ferreira604fe012019-10-17 12:32:00 +01001678 generateCppTag(out, "::android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001679
Steven Moreland616cf4d2018-10-02 13:52:18 -07001680 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1681 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001682 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001683
Steven Moreland69e7c702016-09-09 11:16:32 -07001684 out.unindent();
1685 out << "private:\n";
1686 out.indent();
Neel Mehta9200af02019-07-19 13:24:57 -07001687 out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001688
Neel Mehta19f79792019-05-21 13:39:32 -07001689 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001690
Neel Mehta19f79792019-05-21 13:39:32 -07001691 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001692
Neel Mehta19f79792019-05-21 13:39:32 -07001693 out << "::android::hardware::Return<void> addOnewayTask("
1694 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001695
1696 out.unindent();
1697
1698 out << "};\n\n";
1699
1700 enterLeaveNamespace(out, false /* enter */);
1701
1702 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001703}
1704
Steven Moreland368e4602018-02-16 14:21:49 -08001705void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001706 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001707
Yifan Hong2d7126b2016-10-20 15:12:57 -07001708 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001709 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001710
Steven Moreland368e4602018-02-16 14:21:49 -08001711 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001712 bool reserved = method->isHidlReserved();
1713
1714 if (!reserved) {
1715 out << "// no default implementation for: ";
1716 }
Neel Mehta9200af02019-07-19 13:24:57 -07001717 method->generateCppSignature(out, iface->definedName());
Steven Morelandd4b068a2017-03-20 06:30:51 -07001718 if (reserved) {
1719 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001720 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001721 }).endl();
1722 }
1723
1724 out << "\n";
1725
Steven Moreland368e4602018-02-16 14:21:49 -08001726 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001727 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001728
Yifan Hong3d746092016-12-07 14:26:33 -08001729 for (const Interface *superType : iface->typeChain()) {
Neel Mehta9200af02019-07-19 13:24:57 -07001730 out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1731 << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1732 << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001733 out.indent();
1734 if (iface == superType) {
1735 out << "return parent;\n";
1736 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001737 out << "return ::android::hardware::details::castInterface<";
Neel Mehta9200af02019-07-19 13:24:57 -07001738 out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1739 << iface->getProxyName() << ">(\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001740 out.indent();
1741 out.indent();
1742 out << "parent, \""
1743 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001744 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001745 out.unindent();
1746 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001747 }
Yifan Hong3d746092016-12-07 14:26:33 -08001748 out.unindent();
1749 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001750 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001751}
1752
Steven Moreland368e4602018-02-16 14:21:49 -08001753void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001754 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001755
Yifan Hongeefe4f22017-01-04 15:32:42 -08001756 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001757
Neel Mehta19f79792019-05-21 13:39:32 -07001758 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1759 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
Neel Mehta9200af02019-07-19 13:24:57 -07001760 << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001761
1762 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1763
Yifan Hong2cbc1472016-10-25 19:02:40 -07001764 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001765
Neel Mehta19f79792019-05-21 13:39:32 -07001766 out << "::android::hardware::Return<void> " << klassName
1767 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1768 out.indent();
1769 out << "if (!mOnewayQueue.push(fun)) {\n";
1770 out.indent();
1771 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1772 out.indent();
1773 out.indent();
1774 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1775 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1776 out.unindent();
1777 out.unindent();
1778 out.unindent();
1779 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001780
Neel Mehta19f79792019-05-21 13:39:32 -07001781 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001782
Neel Mehta19f79792019-05-21 13:39:32 -07001783 out.unindent();
1784 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001785}
1786
Steven Moreland92a08a72017-07-31 14:57:37 -07001787void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001788 InstrumentationEvent event,
1789 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001790 const Interface* iface = mRootScope.getInterface();
Neel Mehta9200af02019-07-19 13:24:57 -07001791 std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001792 switch (event) {
1793 case SERVER_API_ENTRY:
1794 {
1795 out << "atrace_begin(ATRACE_TAG_HAL, \""
1796 << baseString + "::server\");\n";
1797 break;
1798 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001799 case PASSTHROUGH_ENTRY:
1800 {
1801 out << "atrace_begin(ATRACE_TAG_HAL, \""
1802 << baseString + "::passthrough\");\n";
1803 break;
1804 }
1805 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001806 case PASSTHROUGH_EXIT:
1807 {
1808 out << "atrace_end(ATRACE_TAG_HAL);\n";
1809 break;
1810 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001811 // client uses scope because of gotos
1812 // this isn't done for server because the profiled code isn't alone in its scope
1813 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1814 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001815 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1816 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001817 break;
1818 }
1819 case CLIENT_API_EXIT:
1820 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001821 default:
1822 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001823 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001824 }
1825 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001826}
1827
Steven Moreland92a08a72017-07-31 14:57:37 -07001828void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001829 Formatter &out,
1830 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001831 const Method *method,
1832 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001833 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001834
Steven Moreland30b76e92017-06-02 18:52:24 -07001835 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001836 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1837 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001838 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001839 std::string event_str = "";
1840 switch (event) {
1841 case SERVER_API_ENTRY:
1842 {
1843 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1844 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001845 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001846 << (arg->type().resultNeedsDeref() ? "" : "&")
1847 << arg->name()
1848 << ");\n";
1849 }
1850 break;
1851 }
1852 case SERVER_API_EXIT:
1853 {
1854 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001855 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001856 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001857 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001858 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001859 }
1860 break;
1861 }
1862 case CLIENT_API_ENTRY:
1863 {
1864 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1865 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001866 out << "_hidl_args.push_back((void *)&"
1867 << arg->name()
1868 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001869 }
1870 break;
1871 }
1872 case CLIENT_API_EXIT:
1873 {
1874 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1875 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001876 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001877 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001878 << "_hidl_out_"
1879 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001880 << ");\n";
1881 }
1882 break;
1883 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001884 case PASSTHROUGH_ENTRY:
1885 {
1886 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1887 for (const auto &arg : method->args()) {
1888 out << "_hidl_args.push_back((void *)&"
1889 << arg->name()
1890 << ");\n";
1891 }
1892 break;
1893 }
1894 case PASSTHROUGH_EXIT:
1895 {
1896 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001897 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001898 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001899 << arg->name()
1900 << ");\n";
1901 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001902 break;
1903 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001904 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001905 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001906 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001907 }
1908 }
1909
Steven Moreland1ab31442016-11-03 18:37:51 -07001910 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001911 out.indent();
Neel Mehta9200af02019-07-19 13:24:57 -07001912 out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1913 << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1914 << "\", \"" << method->name() << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001915 out.unindent();
1916 out << "}\n";
1917 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001918 out << "}\n";
1919 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001920}
1921
Andreas Huber881227d2016-08-02 14:20:21 -07001922} // namespace android