blob: b160a116854afa9b2e5b4fc13b3fef0fba6ccbcc [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070022#include "Interface.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070024#include "Reference.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070025#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070026#include "Scope.h"
27
Andreas Huberdca261f2016-08-04 13:47:51 -070028#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070029#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000030#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070032#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070033#include <vector>
34
35namespace android {
36
Andreas Huber737080b2016-08-02 15:38:04 -070037void AST::getPackageComponents(
38 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070039 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070040}
41
42void AST::getPackageAndVersionComponents(
43 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070044 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070045}
46
Steven Moreland5708edf2016-11-04 15:33:31 +000047std::string AST::makeHeaderGuard(const std::string &baseName,
48 bool indicateGenerated) const {
49 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070050
Steven Moreland5708edf2016-11-04 15:33:31 +000051 if (indicateGenerated) {
52 guard += "HIDL_GENERATED_";
53 }
54
55 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070056 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000057 guard += StringHelper::Uppercase(baseName);
58 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070059
60 return guard;
61}
62
Steven Morelandee88eed2016-10-31 17:49:00 -070063void AST::generateCppPackageInclude(
64 Formatter &out,
65 const FQName &package,
66 const std::string &klass) {
67
68 out << "#include <";
69
70 std::vector<std::string> components;
71 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
72
73 for (const auto &component : components) {
74 out << component << "/";
75 }
76
77 out << klass
78 << ".h>\n";
79}
80
Andreas Huber881227d2016-08-02 14:20:21 -070081void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
82 std::vector<std::string> packageComponents;
83 getPackageAndVersionComponents(
84 &packageComponents, true /* cpp_compatible */);
85
86 if (enter) {
87 for (const auto &component : packageComponents) {
88 out << "namespace " << component << " {\n";
89 }
Andreas Huber0e00de42016-08-03 09:56:02 -070090
Andreas Huber2831d512016-08-15 09:33:47 -070091 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -070092 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -070093 out.setNamespace(std::string());
94
Andreas Huber881227d2016-08-02 14:20:21 -070095 for (auto it = packageComponents.rbegin();
96 it != packageComponents.rend();
97 ++it) {
98 out << "} // namespace " << *it << "\n";
99 }
100 }
101}
102
Steven Moreland038903b2017-03-30 12:11:24 -0700103static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
104 const std::string functionName = isTry ? "tryGetService" : "getService";
105
Steven Moreland7645fbd2019-03-12 18:49:28 -0700106 if (isTry) {
107 DocComment(
108 "This gets the service of this type with the specified instance name. If the\n"
109 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
110 "device, this will return nullptr. This is useful when you don't want to block\n"
111 "during device boot. If getStub is true, this will try to return an unwrapped\n"
112 "passthrough implementation in the same process. This is useful when getting an\n"
113 "implementation from the same partition/compilation group.\n\n"
114 "In general, prefer getService(std::string,bool)")
115 .emit(out);
116 } else {
117 DocComment(
118 "This gets the service of this type with the specified instance name. If the\n"
119 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
120 "nullptr. If the service is not available, this will wait for the service to\n"
121 "become available. If the service is a lazy service, this will start the service\n"
122 "and return when it becomes available. If getStub is true, this will try to\n"
123 "return an unwrapped passthrough implementation in the same process. This is\n"
124 "useful when getting an implementation from the same partition/compilation group.")
125 .emit(out);
126 }
Steven Moreland038903b2017-03-30 12:11:24 -0700127 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800128 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700129 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700130 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800131 << "const char serviceName[], bool getStub=false)"
132 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700133 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700134 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700135 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700139 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700140 DocComment("Calls " + functionName +
141 "(\"default\", bool). This is the recommended instance name for singleton services.")
142 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
144 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
145}
146
147static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
148 declareGetService(out, interfaceName, true /* isTry */);
149 declareGetService(out, interfaceName, false /* isTry */);
150
Steven Moreland7645fbd2019-03-12 18:49:28 -0700151 DocComment(
152 "Registers a service with the service manager. For Trebilized devices, the service\n"
153 "must also be in the VINTF manifest.")
154 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700155 out << "__attribute__ ((warn_unused_result))"
156 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700157 DocComment("Registers for notifications for when a service is registered.").emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "&notification);\n";
163 });
164
165}
166
Steven Moreland038903b2017-03-30 12:11:24 -0700167static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800170
171 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700172 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700174 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000175 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800176 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700177 out << "return ::android::hardware::details::getServiceInternal<"
178 << fqName.getInterfaceProxyName()
179 << ">(serviceName, "
180 << (!isTry ? "true" : "false") // retry
181 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800182 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700183}
184
185static void implementServiceManagerInteractions(Formatter &out,
186 const FQName &fqName, const std::string &package) {
187
188 const std::string interfaceName = fqName.getInterfaceName();
189
190 implementGetService(out, fqName, true /* isTry */);
191 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800192
Yifan Hongeefe4f22017-01-04 15:32:42 -0800193 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800194 << "const std::string &serviceName) ";
195 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700196 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800197 }).endl().endl();
198
Yifan Hongeefe4f22017-01-04 15:32:42 -0800199 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800200 out.indent(2, [&] {
201 out << "const std::string &serviceName,\n"
202 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
203 << "&notification) ";
204 });
205 out.block([&] {
206 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
207 out.indent(2, [&] {
208 out << "= ::android::hardware::defaultServiceManager();\n";
209 });
210 out.sIf("sm == nullptr", [&] {
211 out << "return false;\n";
212 }).endl();
213 out << "::android::hardware::Return<bool> success =\n";
214 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800215 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800216 out.indent(2, [&] {
217 out << "serviceName, notification);\n";
218 });
219 });
220 out << "return success.isOk() && success;\n";
221 }).endl().endl();
222}
223
Steven Moreland368e4602018-02-16 14:21:49 -0800224void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700225 const Interface *iface = getInterface();
226 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700227 const std::string guard = makeHeaderGuard(ifaceName);
228
229 out << "#ifndef " << guard << "\n";
230 out << "#define " << guard << "\n\n";
231
Andreas Huber737080b2016-08-02 15:38:04 -0700232 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700233 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700234 }
235
236 if (!mImportedNames.empty()) {
237 out << "\n";
238 }
239
Steven Moreland19f11b52017-05-12 18:22:21 -0700240 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800241 if (isIBase()) {
242 out << "// skipped #include IServiceNotification.h\n\n";
243 } else {
244 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
245 }
Steven Moreland0693f312016-11-09 15:06:14 -0800246 }
247
Yifan Hongc8934042016-11-17 17:10:52 -0800248 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700249 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700250
Steven Moreland19f11b52017-05-12 18:22:21 -0700251 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200252 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700253 }
254
Martijn Coenenaf712c02016-11-16 15:26:27 +0100255 out << "#include <utils/NativeHandle.h>\n";
256 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700257
258 enterLeaveNamespace(out, true /* enter */);
259 out << "\n";
260
Steven Moreland19f11b52017-05-12 18:22:21 -0700261 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700262 iface->emitDocComment(out);
263
Andreas Huber881227d2016-08-02 14:20:21 -0700264 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700265 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700266
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700267 const Interface *superType = iface->superType();
268
Yi Kong56758da2018-07-24 16:21:37 -0700269 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700271 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000272 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700273 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700274 }
275
276 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700277
278 out.indent();
279
Steven Moreland7645fbd2019-03-12 18:49:28 -0700280 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.")
281 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700282 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700283
Steven Moreland7645fbd2019-03-12 18:49:28 -0700284 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"")
285 .emit(out);
286 out << "static const char* descriptor;\n\n";
287
Steven Moreland70cb55e2019-03-12 17:20:54 -0700288 iface->emitTypeDeclarations(out);
289 } else {
290 mRootScope.emitTypeDeclarations(out);
291 }
Andreas Huber881227d2016-08-02 14:20:21 -0700292
Steven Moreland19f11b52017-05-12 18:22:21 -0700293 if (iface) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700294 DocComment(
295 "Returns whether this object's implementation is outside of the current process.")
296 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800297 out << "virtual bool isRemote() const ";
298 if (!isIBase()) {
299 out << "override ";
300 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700301 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800302
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700303 for (const auto& tuple : iface->allMethodsFromRoot()) {
304 const Method* method = tuple.method();
305
Andreas Huber881227d2016-08-02 14:20:21 -0700306 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700307
Andreas Huber881227d2016-08-02 14:20:21 -0700308 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700309 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800310
311 if (elidedReturn == nullptr && returnsValue) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700312 DocComment("Return callback for " + method->name()).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800313 out << "using "
314 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700315 << "_cb = std::function<void(";
316 method->emitCppResultSignature(out, true /* specify namespaces */);
317 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800318 }
Andreas Huber881227d2016-08-02 14:20:21 -0700319
Andreas Huber3599d922016-08-09 10:42:57 -0700320 method->dumpAnnotations(out);
321
Steven Moreland49bad8d2018-05-17 15:45:26 -0700322 method->emitDocComment(out);
323
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700324 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700325 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700326 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700327 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700328 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700329 }
330
331 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700332 << "(";
333 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700334 out << ")";
335 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800336 if (!isIBase()) {
337 out << " override";
338 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700339 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700340 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700341 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700342 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700343 }
Steven Moreland40786312016-08-16 10:29:40 -0700344
Steven Moreland7645fbd2019-03-12 18:49:28 -0700345 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800346 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700347
Yifan Hong3d746092016-12-07 14:26:33 -0800348 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700349 DocComment(
350 "This performs a checked cast based on what the underlying implementation "
351 "actually is.")
352 .emit(out);
Yifan Hong200209c2017-03-29 03:39:09 -0700353 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800354 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700355 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800356 << superType->getCppArgumentType()
357 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700358 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700359 }
360
Yifan Hongc8934042016-11-17 17:10:52 -0800361 if (isIBase()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700362 out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800363 } else {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700364 out << "\n// helper methods for interactions with the hwservicemanager\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800365 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800366 }
Andreas Huber881227d2016-08-02 14:20:21 -0700367 }
368
Steven Moreland19f11b52017-05-12 18:22:21 -0700369 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700370 out.unindent();
371
Andreas Hubere3f769a2016-10-10 10:54:44 -0700372 out << "};\n\n";
373 }
374
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700375 out << "//\n";
376 out << "// type declarations for package\n";
377 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800378 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700379 out << "//\n";
380 out << "// type header definitions for package\n";
381 out << "//\n\n";
382 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700383
384 out << "\n";
385 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700386 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700387
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700388 out << "//\n";
389 out << "// global type declarations for package\n";
390 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800391 mRootScope.emitGlobalTypeDeclarations(out);
392
Andreas Huber881227d2016-08-02 14:20:21 -0700393 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700394}
395
Steven Moreland368e4602018-02-16 14:21:49 -0800396void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700397 const Interface *iface = getInterface();
398 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700399
Steven Moreland40786312016-08-16 10:29:40 -0700400 const std::string guard = makeHeaderGuard(klassName);
401
402 out << "#ifndef " << guard << "\n";
403 out << "#define " << guard << "\n\n";
404
Steven Moreland19f11b52017-05-12 18:22:21 -0700405 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700406
Steven Morelandee88eed2016-10-31 17:49:00 -0700407 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700408
409 for (const auto &item : mImportedNames) {
410 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800411 generateCppPackageInclude(out, item, "hwtypes");
412 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800413 generateCppPackageInclude(out, item, item.getInterfaceStubName());
414 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700415 }
Steven Moreland40786312016-08-16 10:29:40 -0700416 }
417
418 out << "\n";
419
Martijn Coenen93915102016-09-01 01:35:52 +0200420 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700421 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100422 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700423
424 out << "\n";
425
426 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700427
Steven Moreland368e4602018-02-16 14:21:49 -0800428 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700429
430 enterLeaveNamespace(out, false /* enter */);
431
432 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700433}
434
Steven Moreland58a20c72018-10-09 12:30:51 -0700435static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
436 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800437 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700438 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800439 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700440 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800441 const Interface &iface = static_cast<const Interface &>(arg->type());
442 out << iface.getCppStackType() << " " << wrappedName << ";\n";
443 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
444 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
445 out << wrappedName
446 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700447 << "::android::hardware::details::wrapPassthrough("
448 << name
449 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800450 out.sIf(wrappedName + " == nullptr", [&] {
451 // Fatal error. Happens when the BsFoo class is not found in the binary
452 // or any dynamic libraries.
453 handleError();
454 }).endl();
455 }).sElse([&] {
456 out << wrappedName << " = " << name << ";\n";
457 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700458
459 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800460}
461
Steven Moreland616cf4d2018-10-02 13:52:18 -0700462void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700463 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700464
Steven Moreland58a20c72018-10-09 12:30:51 -0700465 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700466 out.indent();
467
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800468 if (method->isHidlReserved()
469 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
470 method->cppImpl(IMPL_PASSTHROUGH, out);
471 out.unindent();
472 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800473 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800474 }
475
Steven Moreland69e7c702016-09-09 11:16:32 -0700476 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700477 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700478
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700479 generateCppInstrumentationCall(
480 out,
481 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700482 method,
483 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700484
Steven Moreland58a20c72018-10-09 12:30:51 -0700485 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800486 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700487 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800488 out << "return ::android::hardware::Status::fromExceptionCode(\n";
489 out.indent(2, [&] {
490 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800491 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800492 });
493 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700494
495 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800496 }
497
Steven Moreland58a20c72018-10-09 12:30:51 -0700498 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700499 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700500
501 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700502 out << "addOnewayTask([mImpl = this->mImpl\n"
503 << "#ifdef __ANDROID_DEBUGGABLE__\n"
504 ", mEnableInstrumentation = this->mEnableInstrumentation, "
505 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
506 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700507 for (const std::string& arg : wrappedArgNames) {
508 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700509 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700510 out << "] {\n";
511 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700512 }
513
514 out << "mImpl->"
515 << method->name()
516 << "(";
517
Yifan Hong932464e2017-03-30 15:40:22 -0700518 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800519 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700520 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700521
522 std::function<void(void)> kHandlePassthroughError = [&] {
523 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
524 out.indent(2, [&] {
525 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
526 << "\"Cannot wrap passthrough interface.\");\n";
527 });
528 };
529
Steven Moreland69e7c702016-09-09 11:16:32 -0700530 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700531 // never true if oneway since oneway methods don't return values
532
Steven Moreland69e7c702016-09-09 11:16:32 -0700533 if (!method->args().empty()) {
534 out << ", ";
535 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800536 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700537 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800538 out << "const auto &_hidl_out_"
539 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700540 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800541
542 out << ") {\n";
543 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700544 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800545 out,
546 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700547 method,
548 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800549
Steven Moreland58a20c72018-10-09 12:30:51 -0700550 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800551 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700552 wrappedOutNames.push_back(
553 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800554 }
555
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800556 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700557 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
558 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800559 out << ");\n";
560 out.unindent();
561 out << "});\n\n";
562 } else {
563 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700564
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800565 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700566 const std::string outName = "_hidl_out_" + elidedReturn->name();
567
568 out << elidedReturn->type().getCppResultType() << " " << outName
569 << " = _hidl_return;\n";
570 out << "(void) " << outName << ";\n";
571
572 const std::string wrappedName =
573 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
574
575 if (outName != wrappedName) {
576 // update the original value since it is used by generateCppInstrumentationCall
577 out << outName << " = " << wrappedName << ";\n\n";
578
579 // update the value to be returned
580 out << "_hidl_return = " << outName << "\n;";
581 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800582 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700583 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800584 out,
585 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700586 method,
587 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700588 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700589
590 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700591 out.unindent();
592 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700593 } else {
594 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700595 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700596
597 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700598
599 out.unindent();
600 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700601}
602
Steven Moreland368e4602018-02-16 14:21:49 -0800603void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700604 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700605
Yifan Hong10fe0b52016-10-19 14:20:17 -0700606 const Interface *prevIterface = nullptr;
607 for (const auto &tuple : iface->allMethodsFromRoot()) {
608 const Method *method = tuple.method();
609 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700610
Steven Morelandf16c5c02017-07-31 16:50:06 -0700611 if (!includeParent && superInterface != iface) {
612 continue;
613 }
614
Yifan Hong10fe0b52016-10-19 14:20:17 -0700615 if(prevIterface != superInterface) {
616 if (prevIterface != nullptr) {
617 out << "\n";
618 }
619 out << "// Methods from "
620 << superInterface->fullName()
621 << " follow.\n";
622 prevIterface = superInterface;
623 }
Steven Moreland368e4602018-02-16 14:21:49 -0800624 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700625 }
626
Yifan Hong10fe0b52016-10-19 14:20:17 -0700627 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700628}
629
Steven Moreland0b843772017-06-23 16:33:38 -0700630void AST::generateTemplatizationLink(Formatter& out) const {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700631 DocComment("The pure class is what this class wraps.").emit(out);
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700632 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700633}
634
Steven Moreland1a52e822017-07-27 13:56:29 -0700635void AST::generateCppTag(Formatter& out, const std::string& tag) const {
636 out << "typedef " << tag << " _hidl_tag;\n\n";
637}
638
Steven Moreland368e4602018-02-16 14:21:49 -0800639void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800640 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700641
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700642 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800643 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700644 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700645
646 out << "#ifndef " << guard << "\n";
647 out << "#define " << guard << "\n\n";
648
Yifan Hongeefe4f22017-01-04 15:32:42 -0800649 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700650
Steven Morelandee88eed2016-10-31 17:49:00 -0700651 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700652
653 enterLeaveNamespace(out, true /* enter */);
654 out << "\n";
655
656 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800657 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100658 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800659 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000660 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100661 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800662 out << " : public "
663 << gIBaseFqName.getInterfaceStubFqName().cppName()
664 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100665 }
Andreas Huber881227d2016-08-02 14:20:21 -0700666
667 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800668 out << "explicit "
669 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700670 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100671 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800672 out << "explicit "
673 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700674 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800675 << " const std::string& HidlInstrumentor_package,"
676 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700677 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000678 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700679 out << "::android::status_t onTransact(\n";
680 out.indent();
681 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700682 out << "uint32_t _hidl_code,\n";
683 out << "const ::android::hardware::Parcel &_hidl_data,\n";
684 out << "::android::hardware::Parcel *_hidl_reply,\n";
685 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700686 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700687 out.unindent();
688 out.unindent();
689
Steven Moreland0b843772017-06-23 16:33:38 -0700690 out.endl();
691 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700692 DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
693 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700694 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700695
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800696 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700697
Steven Moreland368e4602018-02-16 14:21:49 -0800698 generateMethods(out,
699 [&](const Method* method, const Interface*) {
700 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
701 return;
702 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700703
Steven Moreland368e4602018-02-16 14:21:49 -0800704 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700705
Steven Moreland368e4602018-02-16 14:21:49 -0800706 out.indent(2,
707 [&] {
708 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
709 << "const ::android::hardware::Parcel &_hidl_data,\n"
710 << "::android::hardware::Parcel *_hidl_reply,\n"
711 << "TransactCallback _hidl_cb);\n";
712 })
713 .endl()
714 .endl();
715 },
716 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700717
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100718 out.unindent();
719 out << "private:\n";
720 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800721
Steven Moreland368e4602018-02-16 14:21:49 -0800722 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800723 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800724 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800725 }
726 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700727 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800728
729 if (elidedReturn == nullptr && returnsValue) {
730 out << "using " << method->name() << "_cb = "
731 << iface->fqName().cppName()
732 << "::" << method->name() << "_cb;\n";
733 }
734 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800735 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800736 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800737
Steven Moreland19f11b52017-05-12 18:22:21 -0700738 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700739 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700740 out << "};\n\n";
741
742 enterLeaveNamespace(out, false /* enter */);
743
744 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700745}
746
Steven Moreland368e4602018-02-16 14:21:49 -0800747void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700748 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700749 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800750 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700751 }
752
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700753 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800754 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800755 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700756
757 out << "#ifndef " << guard << "\n";
758 out << "#define " << guard << "\n\n";
759
Martijn Coenen115d4282016-12-19 05:14:04 +0100760 out << "#include <hidl/HidlTransportSupport.h>\n\n";
761
Andreas Huber881227d2016-08-02 14:20:21 -0700762 std::vector<std::string> packageComponents;
763 getPackageAndVersionComponents(
764 &packageComponents, false /* cpp_compatible */);
765
Yifan Hongeefe4f22017-01-04 15:32:42 -0800766 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700767 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700768
769 enterLeaveNamespace(out, true /* enter */);
770 out << "\n";
771
772 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800773 << proxyName
774 << " : public ::android::hardware::BpInterface<"
775 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000776 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700777
778 out.indent();
779
Yifan Hongeefe4f22017-01-04 15:32:42 -0800780 out << "explicit "
781 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700782 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700783 << "\n\n";
784
Steven Moreland0b843772017-06-23 16:33:38 -0700785 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700786 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
787 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700788 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700789
Yifan Hong10fe0b52016-10-19 14:20:17 -0700790 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700791
Steven Moreland368e4602018-02-16 14:21:49 -0800792 generateMethods(
793 out,
794 [&](const Method* method, const Interface*) {
795 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
796 return;
797 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700798
Steven Moreland368e4602018-02-16 14:21:49 -0800799 out << "static ";
800 method->generateCppReturnType(out);
801 out << " _hidl_" << method->name() << "("
802 << "::android::hardware::IInterface* _hidl_this, "
803 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700804
Steven Moreland368e4602018-02-16 14:21:49 -0800805 if (!method->hasEmptyCppArgSignature()) {
806 out << ", ";
807 }
808 method->emitCppArgSignature(out);
809 out << ");\n";
810 },
811 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700812
Steven Moreland368e4602018-02-16 14:21:49 -0800813 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700814 method->generateCppSignature(out);
815 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700816 });
Steven Moreland9c387612016-09-07 09:54:26 -0700817
Andreas Huber881227d2016-08-02 14:20:21 -0700818 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100819 out << "private:\n";
820 out.indent();
821 out << "std::mutex _hidl_mMutex;\n"
822 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
823 << " _hidl_mDeathRecipients;\n";
824 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700825 out << "};\n\n";
826
827 enterLeaveNamespace(out, false /* enter */);
828
829 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700830}
831
Steven Moreland368e4602018-02-16 14:21:49 -0800832void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700833 std::string baseName = getBaseName();
834 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700835
Steven Morelanda885d252017-09-25 18:44:43 -0700836 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700837
Steven Moreland623c0042017-01-13 14:42:29 -0800838 out << "#define LOG_TAG \""
839 << mPackage.string() << "::" << baseName
840 << "\"\n\n";
841
Steven Moreland5add34d2018-11-08 16:31:30 -0800842 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100843 out << "#include <cutils/trace.h>\n";
844 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700845 out << "#include <hidl/Static.h>\n";
846 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700847 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700848 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700849 // This is a no-op for IServiceManager itself.
850 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
851
Yifan Hongeefe4f22017-01-04 15:32:42 -0800852 generateCppPackageInclude(out, mPackage, iface->getProxyName());
853 generateCppPackageInclude(out, mPackage, iface->getStubName());
854 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700855
856 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700857 generateCppPackageInclude(out,
858 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800859 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700860 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800861
862 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700863 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700864 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800865 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700866 }
867
868 out << "\n";
869
870 enterLeaveNamespace(out, true /* enter */);
871 out << "\n";
872
Steven Moreland368e4602018-02-16 14:21:49 -0800873 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700874
Steven Moreland368e4602018-02-16 14:21:49 -0800875 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700876 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700877
878 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800879 out << "const char* "
880 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700881 << "::descriptor(\""
882 << iface->fqName().string()
883 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800884 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100885 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800886 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800887 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800888 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800889 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800890 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800891 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800892 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800893 out << "return new "
894 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700895 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800896 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800897 << " *>(iIntf));\n";
898 });
Yifan Hongb04de382017-02-06 15:31:52 -0800899 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800900 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800901 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800902 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800903 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800904 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800905 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800906 << gIBaseFqName.cppName()
907 << "> {\n";
908 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800909 out << "return new "
910 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700911 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800912 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800913 << " *>(iIntf));\n";
914 });
Yifan Hongb04de382017-02-06 15:31:52 -0800915 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800916 });
Yifan Hong158655a2016-11-08 12:34:07 -0800917 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100918 out << "};\n\n";
919 out << "__attribute__((destructor))";
920 out << "static void static_destructor() {\n";
921 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800922 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100923 << iface->localName()
924 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800925 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100926 << iface->localName()
927 << "::descriptor);\n";
928 });
929 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800930
Steven Moreland368e4602018-02-16 14:21:49 -0800931 generateInterfaceSource(out);
932 generateProxySource(out, iface->fqName());
933 generateStubSource(out, iface);
934 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700935
Yifan Hongc8934042016-11-17 17:10:52 -0800936 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800937 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800938 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800939 std::string package = iface->fqName().package()
940 + iface->fqName().atVersion();
941
Yifan Hongeefe4f22017-01-04 15:32:42 -0800942 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800943 }
Steven Moreland40786312016-08-16 10:29:40 -0700944 }
945
Andreas Huber6755e9d2017-04-06 11:09:07 -0700946 HidlTypeAssertion::EmitAll(out);
947 out << "\n";
948
Andreas Huber881227d2016-08-02 14:20:21 -0700949 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700950}
951
Steven Moreland368e4602018-02-16 14:21:49 -0800952void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
953 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700954}
955
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700956void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
957 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700958 if (args.empty()) {
959 return;
960 }
961
962 for (const auto &arg : args) {
963 const Type &type = arg->type();
964
Yifan Hong3b320f82016-11-01 15:15:54 -0700965 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700966 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700967 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700968 << ";\n";
969 }
970
971 out << "\n";
972}
973
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700974void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
975 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
976 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700977 const Type &type = arg->type();
978
Andreas Huber881227d2016-08-02 14:20:21 -0700979 type.emitReaderWriter(
980 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700981 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700982 parcelObj,
983 parcelObjIsPointer,
984 isReader,
985 mode);
986}
987
Steven Moreland368e4602018-02-16 14:21:49 -0800988void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
989 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700990 method->generateCppSignature(out,
991 klassName,
992 true /* specify namespaces */);
993
Martijn Coenen115d4282016-12-19 05:14:04 +0100994 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -0700995 out.block([&] {
996 method->cppImpl(IMPL_PROXY, out);
997 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -0800998 return;
Martijn Coenen115d4282016-12-19 05:14:04 +0100999 }
1000
Steven Morelandf16c5c02017-07-31 16:50:06 -07001001 out.block([&] {
1002 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001003 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001004
1005 method->generateCppReturnType(out);
1006
1007 out << " _hidl_out = "
1008 << superInterface->fqName().cppNamespace()
1009 << "::"
1010 << superInterface->getProxyName()
1011 << "::_hidl_"
1012 << method->name()
1013 << "(this, this";
1014
1015 if (!method->hasEmptyCppArgSignature()) {
1016 out << ", ";
1017 }
1018
1019 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1020 out << arg->name();
1021 });
1022
1023 if (returnsValue && elidedReturn == nullptr) {
1024 if (!method->args().empty()) {
1025 out << ", ";
1026 }
1027 out << "_hidl_cb";
1028 }
1029
1030 out << ");\n\n";
1031
1032 out << "return _hidl_out;\n";
1033 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001034}
1035
Steven Moreland368e4602018-02-16 14:21:49 -08001036void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001037 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001038 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001039 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001040 }
1041
1042 method->generateCppReturnType(out);
1043
1044 out << klassName
1045 << "::_hidl_"
1046 << method->name()
1047 << "("
1048 << "::android::hardware::IInterface *_hidl_this, "
1049 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1050
1051 if (!method->hasEmptyCppArgSignature()) {
1052 out << ", ";
1053 }
1054
1055 method->emitCppArgSignature(out);
1056 out << ") {\n";
1057
1058 out.indent();
1059
1060 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1061 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1062 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1063 out << "#else\n";
1064 out << "(void) _hidl_this_instrumentor;\n";
1065 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1066
1067 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001068 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001069 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1070
Steven Moreland92a08a72017-07-31 14:57:37 -07001071 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001072 out,
1073 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001074 method,
1075 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001076
1077 out << "::android::hardware::Parcel _hidl_data;\n";
1078 out << "::android::hardware::Parcel _hidl_reply;\n";
1079 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001080 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001081 out << "::android::hardware::Status _hidl_status;\n\n";
1082
Steven Moreland48cc6042019-04-30 11:28:56 -07001083 if (!hasCallback) {
1084 declareCppReaderLocals(
1085 out, method->results(), true /* forResults */);
1086 }
Yifan Hong068c5522016-10-31 14:07:25 -07001087
1088 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001089 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001090 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001091 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1092
Martijn Coenenfff73352017-01-04 16:36:31 +01001093 bool hasInterfaceArgument = false;
Steven Moreland8249f0a2019-05-28 17:25:27 -07001094
Yifan Hong068c5522016-10-31 14:07:25 -07001095 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001096 if (arg->type().isInterface()) {
1097 hasInterfaceArgument = true;
1098 }
Yifan Hong068c5522016-10-31 14:07:25 -07001099 emitCppReaderWriter(
1100 out,
1101 "_hidl_data",
1102 false /* parcelObjIsPointer */,
1103 arg,
1104 false /* reader */,
1105 Type::ErrorMode_Goto,
1106 false /* addPrefixToName */);
1107 }
1108
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001109 if (hasInterfaceArgument) {
1110 // Start binder threadpool to handle incoming transactions
1111 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1112 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001113 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001114 << method->getSerialId()
1115 << " /* "
1116 << method->name()
1117 << " */, _hidl_data, &_hidl_reply";
1118
1119 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001120 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001121 } else {
1122 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001123 }
Yifan Hong068c5522016-10-31 14:07:25 -07001124
Steven Moreland48cc6042019-04-30 11:28:56 -07001125 if (hasCallback) {
1126 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1127 out.indent();
1128 declareCppReaderLocals(
1129 out, method->results(), true /* forResults */);
1130 out.endl();
1131 } else {
1132 out << ");\n";
1133 out << "if (_hidl_transact_err != ::android::OK) \n";
1134 out.block([&] {
1135 out << "_hidl_err = _hidl_transact_err;\n";
1136 out << "goto _hidl_error;\n";
1137 }).endl().endl();
1138 }
Yifan Hong068c5522016-10-31 14:07:25 -07001139
1140 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001141 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001142
Steven Moreland48cc6042019-04-30 11:28:56 -07001143 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1144 Type::handleError(out, errorMode);
1145
1146 if (hasCallback) {
1147 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1148 } else {
1149 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1150 }
Yifan Hong068c5522016-10-31 14:07:25 -07001151
Yifan Hong068c5522016-10-31 14:07:25 -07001152 for (const auto &arg : method->results()) {
1153 emitCppReaderWriter(
1154 out,
1155 "_hidl_reply",
1156 false /* parcelObjIsPointer */,
1157 arg,
1158 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001159 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001160 true /* addPrefixToName */);
1161 }
1162
Yifan Hong068c5522016-10-31 14:07:25 -07001163 if (returnsValue && elidedReturn == nullptr) {
1164 out << "_hidl_cb(";
1165
Yifan Hong932464e2017-03-30 15:40:22 -07001166 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001167 if (arg->type().resultNeedsDeref()) {
1168 out << "*";
1169 }
1170 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001171 });
Yifan Hong068c5522016-10-31 14:07:25 -07001172
1173 out << ");\n\n";
1174 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001175 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001176
Steven Moreland92a08a72017-07-31 14:57:37 -07001177 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001178 out,
1179 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001180 method,
1181 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001182
Steven Moreland48cc6042019-04-30 11:28:56 -07001183 if (hasCallback) {
1184 out.unindent();
1185 out << "});\n";
1186 out << "if (_hidl_transact_err != ::android::OK) ";
1187 out.block([&] {
1188 out << "_hidl_err = _hidl_transact_err;\n";
1189 out << "goto _hidl_error;\n";
1190 }).endl().endl();
1191 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1192 }
1193
Yifan Hong068c5522016-10-31 14:07:25 -07001194 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001195 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001196 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001197 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1198 } else {
Yifan Hong068c5522016-10-31 14:07:25 -07001199 out << "return ::android::hardware::Return<void>();\n\n";
1200 }
1201
1202 out.unindent();
1203 out << "_hidl_error:\n";
1204 out.indent();
1205 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1206 out << "return ::android::hardware::Return<";
1207 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001208 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001209 } else {
1210 out << "void";
1211 }
1212 out << ">(_hidl_status);\n";
1213
1214 out.unindent();
1215 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001216}
1217
Steven Moreland368e4602018-02-16 14:21:49 -08001218void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001219 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001220
1221 out << klassName
1222 << "::"
1223 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001224 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001225
1226 out.indent();
1227 out.indent();
1228
1229 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001230 << "<"
1231 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001232 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001233 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001234 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001235 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001236 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001237 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001238
Andreas Huber881227d2016-08-02 14:20:21 -07001239 out.unindent();
1240 out.unindent();
1241 out << "}\n\n";
1242
Steven Moreland368e4602018-02-16 14:21:49 -08001243 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001244 [&](const Method* method, const Interface* superInterface) {
1245 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001246 },
1247 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001248
Steven Moreland368e4602018-02-16 14:21:49 -08001249 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1250 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001251 });
Andreas Huber881227d2016-08-02 14:20:21 -07001252}
1253
Steven Moreland368e4602018-02-16 14:21:49 -08001254void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001255 const std::string interfaceName = iface->localName();
1256 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001257
Steven Moreland40786312016-08-16 10:29:40 -07001258 out << klassName
1259 << "::"
1260 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001261 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001262
1263 out.indent();
1264 out.indent();
1265
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001266 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001267 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001268 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001269 out << ": "
1270 << gIBaseFqName.getInterfaceStubFqName().cppName()
1271 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001272 }
1273
1274 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001275 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001276 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001277 << "\") { \n";
1278 out.indent();
1279 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001280 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001281 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1282 out << "mSchedPolicy = prio.sched_policy;\n";
1283 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001284 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1285 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001286 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001287
1288 out.unindent();
1289 out.unindent();
1290 out << "}\n\n";
1291
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001292 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001293 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001294 // class properly.
1295 out << klassName
1296 << "::"
1297 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001298 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1299 << " const std::string &HidlInstrumentor_package,"
1300 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001301
1302 out.indent();
1303 out.indent();
1304
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001305 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001306 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001307 out.indent();
1308 out << "_hidl_mImpl = _hidl_impl;\n";
1309 out.unindent();
1310
1311 out.unindent();
1312 out.unindent();
1313 out << "}\n\n";
1314 }
1315
Steven Moreland57a89362017-07-21 19:29:54 +00001316 out << klassName << "::~" << klassName << "() ";
1317 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001318 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1319 })
1320 .endl()
1321 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001322
Steven Moreland368e4602018-02-16 14:21:49 -08001323 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001324 [&](const Method* method, const Interface* superInterface) {
1325 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001326 },
1327 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001328
Steven Moreland368e4602018-02-16 14:21:49 -08001329 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001330 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001331 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001332 }
1333 method->generateCppSignature(out, iface->getStubName());
1334 out << " ";
1335 out.block([&] {
1336 method->cppImpl(IMPL_STUB_IMPL, out);
1337 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001338 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001339
Andreas Huber881227d2016-08-02 14:20:21 -07001340 out << "::android::status_t " << klassName << "::onTransact(\n";
1341
1342 out.indent();
1343 out.indent();
1344
Iliyan Malchev549e2592016-08-10 08:59:12 -07001345 out << "uint32_t _hidl_code,\n"
1346 << "const ::android::hardware::Parcel &_hidl_data,\n"
1347 << "::android::hardware::Parcel *_hidl_reply,\n"
1348 << "uint32_t _hidl_flags,\n"
1349 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001350
1351 out.unindent();
1352
Iliyan Malchev549e2592016-08-10 08:59:12 -07001353 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001354 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001355 out.indent();
1356
Yifan Hong10fe0b52016-10-19 14:20:17 -07001357 for (const auto &tuple : iface->allMethodsFromRoot()) {
1358 const Method *method = tuple.method();
1359 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001360
Howard Chen71f289f2017-08-29 17:35:01 +08001361 if (!isIBase() && method->isHidlReserved()) {
1362 continue;
1363 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001364 out << "case "
1365 << method->getSerialId()
1366 << " /* "
1367 << method->name()
1368 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001369
Yifan Hong10fe0b52016-10-19 14:20:17 -07001370 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001371
Steven Moreland77943692018-08-09 12:53:42 -07001372 out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
1373 << ";\n";
Steven Morelandebd8c722017-11-03 14:47:32 -07001374 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
1375 out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
1376
Steven Moreland368e4602018-02-16 14:21:49 -08001377 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001378
1379 out.unindent();
1380 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001381 }
1382
1383 out << "default:\n{\n";
1384 out.indent();
1385
Martijn Coenen225bc922017-06-27 14:39:46 -07001386 if (iface->isIBase()) {
1387 out << "(void)_hidl_flags;\n";
1388 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1389 } else {
1390 out << "return ";
1391 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1392 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001393
Martijn Coenen225bc922017-06-27 14:39:46 -07001394 out.indent();
1395 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001396
Martijn Coenen225bc922017-06-27 14:39:46 -07001397 out << "_hidl_code, _hidl_data, _hidl_reply, "
1398 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001399
Martijn Coenen225bc922017-06-27 14:39:46 -07001400 out.unindent();
1401 out.unindent();
1402 }
Andreas Huber881227d2016-08-02 14:20:21 -07001403
1404 out.unindent();
1405 out << "}\n";
1406
1407 out.unindent();
1408 out << "}\n\n";
1409
Yifan Honga018ed52016-12-13 16:35:08 -08001410 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1411 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1412 out.indent(2, [&] {
1413 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1414 out << "_hidl_reply);\n";
1415 });
1416 });
Andreas Huber881227d2016-08-02 14:20:21 -07001417
Iliyan Malchev549e2592016-08-10 08:59:12 -07001418 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001419
1420 out.unindent();
1421 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001422}
1423
Steven Moreland368e4602018-02-16 14:21:49 -08001424void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1425 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001426 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1427 method->cppImpl(IMPL_STUB, out);
1428 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001429 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001430 }
1431
Steven Morelandf16c5c02017-07-31 16:50:06 -07001432 out << "_hidl_err = "
1433 << superInterface->fqName().cppNamespace()
1434 << "::"
1435 << superInterface->getStubName()
1436 << "::_hidl_"
1437 << method->name()
1438 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1439 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001440}
1441
Steven Moreland368e4602018-02-16 14:21:49 -08001442void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001443 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001444 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001445 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001446 }
1447
Steven Morelandf8197902018-01-30 15:38:37 -08001448 const std::string& klassName = fqName.getInterfaceStubName();
1449
Steven Morelandf16c5c02017-07-31 16:50:06 -07001450 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1451
1452 out.indent();
1453 out.indent();
1454
1455 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1456 << "const ::android::hardware::Parcel &_hidl_data,\n"
1457 << "::android::hardware::Parcel *_hidl_reply,\n"
1458 << "TransactCallback _hidl_cb) {\n";
1459
1460 out.unindent();
1461
1462 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1463 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1464 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1465 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1466
1467 out << "::android::status_t _hidl_err = ::android::OK;\n";
1468
Yifan Hongeefe4f22017-01-04 15:32:42 -08001469 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001470 << klassName
1471 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001472
Andreas Huber881227d2016-08-02 14:20:21 -07001473 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001474 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001475 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001476 out.unindent();
1477 out << "}\n\n";
1478
Andreas Huber5e44a292016-09-27 14:52:39 -07001479 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001480
Andreas Huber881227d2016-08-02 14:20:21 -07001481 for (const auto &arg : method->args()) {
1482 emitCppReaderWriter(
1483 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001484 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001485 false /* parcelObjIsPointer */,
1486 arg,
1487 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001488 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001489 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001490 }
1491
Steven Moreland92a08a72017-07-31 14:57:37 -07001492 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001493 out,
1494 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001495 method,
1496 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001497
Andreas Huber881227d2016-08-02 14:20:21 -07001498 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001499 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001500
1501 std::string callee;
1502
1503 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1504 callee = "_hidl_this";
1505 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001506 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001507 }
Andreas Huber881227d2016-08-02 14:20:21 -07001508
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001509 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001510 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001511 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001512 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001513 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001514 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001515 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001516
Yifan Hong932464e2017-03-30 15:40:22 -07001517 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001518 if (arg->type().resultNeedsDeref()) {
1519 out << "*";
1520 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001521 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001522 });
Andreas Huber881227d2016-08-02 14:20:21 -07001523
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001524 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001525
Yifan Hong859e53f2016-11-14 19:08:24 -08001526 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1527 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001528
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001529 elidedReturn->type().emitReaderWriter(
1530 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001531 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001532 "_hidl_reply",
1533 true, /* parcelObjIsPointer */
1534 false, /* isReader */
1535 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001536
Steven Moreland92a08a72017-07-31 14:57:37 -07001537 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001538 out,
1539 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001540 method,
1541 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001542
Iliyan Malchev549e2592016-08-10 08:59:12 -07001543 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001544 } else {
1545 if (returnsValue) {
1546 out << "bool _hidl_callbackCalled = false;\n\n";
1547 }
Andreas Huber881227d2016-08-02 14:20:21 -07001548
Steven Moreland30232dc2019-03-05 19:39:10 -08001549 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1550 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001551
Yifan Hong932464e2017-03-30 15:40:22 -07001552 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001553 if (arg->type().resultNeedsDeref()) {
1554 out << "*";
1555 }
1556
1557 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001558 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001559
1560 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001561 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001562 out << ", ";
1563 }
1564
1565 out << "[&](";
1566
Yifan Hong932464e2017-03-30 15:40:22 -07001567 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001568 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001569 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001570
1571 out << ") {\n";
1572 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001573 out << "if (_hidl_callbackCalled) {\n";
1574 out.indent();
1575 out << "LOG_ALWAYS_FATAL(\""
1576 << method->name()
1577 << ": _hidl_cb called a second time, but must be called once.\");\n";
1578 out.unindent();
1579 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001580 out << "_hidl_callbackCalled = true;\n\n";
1581
Yifan Hong859e53f2016-11-14 19:08:24 -08001582 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1583 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001584
1585 for (const auto &arg : method->results()) {
1586 emitCppReaderWriter(
1587 out,
1588 "_hidl_reply",
1589 true /* parcelObjIsPointer */,
1590 arg,
1591 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001592 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001593 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001594 }
1595
Steven Moreland92a08a72017-07-31 14:57:37 -07001596 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001597 out,
1598 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001599 method,
1600 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001601
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001602 out << "_hidl_cb(*_hidl_reply);\n";
1603
1604 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001605 out << "});\n\n";
1606 } else {
1607 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001608 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001609 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001610 out,
1611 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001612 method,
1613 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001614 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001615
Steven Moreland30232dc2019-03-05 19:39:10 -08001616 out << "_hidl_ret.assertOk();\n";
1617
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001618 if (returnsValue) {
1619 out << "if (!_hidl_callbackCalled) {\n";
1620 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001621 out << "LOG_ALWAYS_FATAL(\""
1622 << method->name()
1623 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001624 out.unindent();
1625 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001626 } else {
1627 out << "::android::hardware::writeToParcel("
1628 << "::android::hardware::Status::ok(), "
1629 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001630 }
Andreas Huber881227d2016-08-02 14:20:21 -07001631 }
1632
Steven Morelandf16c5c02017-07-31 16:50:06 -07001633 out << "return _hidl_err;\n";
1634 out.unindent();
1635 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001636}
1637
Steven Moreland368e4602018-02-16 14:21:49 -08001638void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001639 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001640 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001641 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001642 }
1643
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001644 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001645 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001646
Yifan Hongeefe4f22017-01-04 15:32:42 -08001647 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001648
Steven Moreland69e7c702016-09-09 11:16:32 -07001649 const std::string guard = makeHeaderGuard(klassName);
1650
1651 out << "#ifndef " << guard << "\n";
1652 out << "#define " << guard << "\n\n";
1653
1654 std::vector<std::string> packageComponents;
1655 getPackageAndVersionComponents(
1656 &packageComponents, false /* cpp_compatible */);
1657
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001658 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001659 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001660 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001661
Steven Moreland19f11b52017-05-12 18:22:21 -07001662 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001663 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001664
Yifan Hong7a118f52016-12-07 11:21:15 -08001665 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Neel Mehta19f79792019-05-21 13:39:32 -07001666 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001667
1668 enterLeaveNamespace(out, true /* enter */);
1669 out << "\n";
1670
1671 out << "struct "
1672 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001673 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001674 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001675
1676 out.indent();
1677 out << "explicit "
1678 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001679 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001680 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001681 << "> impl);\n";
1682
Steven Moreland0b843772017-06-23 16:33:38 -07001683 out.endl();
1684 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001685 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001686
Steven Moreland616cf4d2018-10-02 13:52:18 -07001687 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1688 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001689 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001690
Steven Moreland69e7c702016-09-09 11:16:32 -07001691 out.unindent();
1692 out << "private:\n";
1693 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001694 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001695
Neel Mehta19f79792019-05-21 13:39:32 -07001696 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001697
Neel Mehta19f79792019-05-21 13:39:32 -07001698 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001699
Neel Mehta19f79792019-05-21 13:39:32 -07001700 out << "::android::hardware::Return<void> addOnewayTask("
1701 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001702
1703 out.unindent();
1704
1705 out << "};\n\n";
1706
1707 enterLeaveNamespace(out, false /* enter */);
1708
1709 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001710}
1711
Steven Moreland368e4602018-02-16 14:21:49 -08001712void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001713 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001714
Yifan Hong2d7126b2016-10-20 15:12:57 -07001715 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001716 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001717
Steven Moreland368e4602018-02-16 14:21:49 -08001718 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001719 bool reserved = method->isHidlReserved();
1720
1721 if (!reserved) {
1722 out << "// no default implementation for: ";
1723 }
1724 method->generateCppSignature(out, iface->localName());
1725 if (reserved) {
1726 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001727 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001728 }).endl();
1729 }
1730
1731 out << "\n";
1732
Steven Moreland368e4602018-02-16 14:21:49 -08001733 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001734 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001735
Yifan Hong3d746092016-12-07 14:26:33 -08001736 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001737 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001738 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001739 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001740 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001741 << "::castFrom("
1742 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001743 << " parent, bool "
1744 << (iface == superType ? "/* emitError */" : "emitError")
1745 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001746 out.indent();
1747 if (iface == superType) {
1748 out << "return parent;\n";
1749 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001750 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001751 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001752 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001753 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001754 << ">(\n";
1755 out.indent();
1756 out.indent();
1757 out << "parent, \""
1758 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001759 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001760 out.unindent();
1761 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001762 }
Yifan Hong3d746092016-12-07 14:26:33 -08001763 out.unindent();
1764 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001765 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001766}
1767
Steven Moreland368e4602018-02-16 14:21:49 -08001768void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001769 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001770
Yifan Hongeefe4f22017-01-04 15:32:42 -08001771 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001772
Neel Mehta19f79792019-05-21 13:39:32 -07001773 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1774 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1775 << "\", \"" << iface->localName() << "\"), mImpl(impl) {\n";
1776
1777 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1778
Yifan Hong2cbc1472016-10-25 19:02:40 -07001779 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001780
Neel Mehta19f79792019-05-21 13:39:32 -07001781 out << "::android::hardware::Return<void> " << klassName
1782 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1783 out.indent();
1784 out << "if (!mOnewayQueue.push(fun)) {\n";
1785 out.indent();
1786 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1787 out.indent();
1788 out.indent();
1789 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1790 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1791 out.unindent();
1792 out.unindent();
1793 out.unindent();
1794 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001795
Neel Mehta19f79792019-05-21 13:39:32 -07001796 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001797
Neel Mehta19f79792019-05-21 13:39:32 -07001798 out.unindent();
1799 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001800}
1801
Steven Moreland92a08a72017-07-31 14:57:37 -07001802void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001803 InstrumentationEvent event,
1804 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001805 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001806 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001807 switch (event) {
1808 case SERVER_API_ENTRY:
1809 {
1810 out << "atrace_begin(ATRACE_TAG_HAL, \""
1811 << baseString + "::server\");\n";
1812 break;
1813 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001814 case PASSTHROUGH_ENTRY:
1815 {
1816 out << "atrace_begin(ATRACE_TAG_HAL, \""
1817 << baseString + "::passthrough\");\n";
1818 break;
1819 }
1820 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001821 case PASSTHROUGH_EXIT:
1822 {
1823 out << "atrace_end(ATRACE_TAG_HAL);\n";
1824 break;
1825 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001826 // client uses scope because of gotos
1827 // this isn't done for server because the profiled code isn't alone in its scope
1828 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1829 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001830 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1831 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001832 break;
1833 }
1834 case CLIENT_API_EXIT:
1835 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001836 default:
1837 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001838 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001839 }
1840 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001841}
1842
Steven Moreland92a08a72017-07-31 14:57:37 -07001843void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001844 Formatter &out,
1845 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001846 const Method *method,
1847 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001848 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001849
Steven Moreland30b76e92017-06-02 18:52:24 -07001850 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001851 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1852 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001853 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001854 std::string event_str = "";
1855 switch (event) {
1856 case SERVER_API_ENTRY:
1857 {
1858 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1859 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001860 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001861 << (arg->type().resultNeedsDeref() ? "" : "&")
1862 << arg->name()
1863 << ");\n";
1864 }
1865 break;
1866 }
1867 case SERVER_API_EXIT:
1868 {
1869 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001870 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001871 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001872 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001873 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001874 }
1875 break;
1876 }
1877 case CLIENT_API_ENTRY:
1878 {
1879 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1880 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001881 out << "_hidl_args.push_back((void *)&"
1882 << arg->name()
1883 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001884 }
1885 break;
1886 }
1887 case CLIENT_API_EXIT:
1888 {
1889 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1890 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001891 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001892 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001893 << "_hidl_out_"
1894 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001895 << ");\n";
1896 }
1897 break;
1898 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001899 case PASSTHROUGH_ENTRY:
1900 {
1901 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1902 for (const auto &arg : method->args()) {
1903 out << "_hidl_args.push_back((void *)&"
1904 << arg->name()
1905 << ");\n";
1906 }
1907 break;
1908 }
1909 case PASSTHROUGH_EXIT:
1910 {
1911 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001912 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001913 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001914 << arg->name()
1915 << ");\n";
1916 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001917 break;
1918 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001919 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001920 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001921 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001922 }
1923 }
1924
Steven Moreland1ab31442016-11-03 18:37:51 -07001925 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001926 out.indent();
1927 out << "callback("
1928 << event_str
1929 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001930 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001931 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001932 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001933 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001934 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001935 << "\", \""
1936 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001937 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001938 out.unindent();
1939 out << "}\n";
1940 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001941 out << "}\n";
1942 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001943}
1944
Andreas Huber881227d2016-08-02 14:20:21 -07001945} // namespace android