blob: e030d8279e53e298ac25250901248cca809ddbe9 [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 Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
55 generatePassthroughHeader(outputPath);
56 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Andreas Huberb82318c2016-08-02 14:45:54 -0700128status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700129
Andreas Huberb82318c2016-08-02 14:45:54 -0700130 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700131 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700132 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700133
134 std::string ifaceName;
135 bool isInterface = true;
136 if (!AST::isInterface(&ifaceName)) {
137 ifaceName = "types";
138 isInterface = false;
139 }
140 path.append(ifaceName);
141 path.append(".h");
142
Andreas Huberd2943e12016-08-05 11:59:31 -0700143 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700144 FILE *file = fopen(path.c_str(), "w");
145
146 if (file == NULL) {
147 return -errno;
148 }
149
150 Formatter out(file);
151
152 const std::string guard = makeHeaderGuard(ifaceName);
153
154 out << "#ifndef " << guard << "\n";
155 out << "#define " << guard << "\n\n";
156
Andreas Huber737080b2016-08-02 15:38:04 -0700157 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700158 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700159 }
160
161 if (!mImportedNames.empty()) {
162 out << "\n";
163 }
164
Steven Moreland0693f312016-11-09 15:06:14 -0800165 if (isInterface) {
166 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
167 }
168
Yifan Hong859e53f2016-11-14 19:08:24 -0800169 // TODO b/32756130 change back to HidlSupport.h
170 out << "#include <hidl/HidlTransportSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700171 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700172
173 if (isInterface) {
Steven Moreland0693f312016-11-09 15:06:14 -0800174 out << "#include <hidl/ServiceManagement.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200175 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700176 }
177
Martijn Coenenaf712c02016-11-16 15:26:27 +0100178 out << "#include <utils/NativeHandle.h>\n";
179 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700180
181 enterLeaveNamespace(out, true /* enter */);
182 out << "\n";
183
184 if (isInterface) {
185 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700186 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700187
188 const Interface *iface = mRootScope->getInterface();
189 const Interface *superType = iface->superType();
190
Steven Moreland40786312016-08-16 10:29:40 -0700191 if (superType == NULL) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800192 out << " : virtual public ::android::hardware::IBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700193 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000194 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700195 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700196 }
197
198 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700199
200 out.indent();
201
Andreas Huber881227d2016-08-02 14:20:21 -0700202 }
203
204 status_t err = emitTypeDeclarations(out);
205
206 if (err != OK) {
207 return err;
208 }
209
210 if (isInterface) {
211 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700212 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700213 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700214 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200215 << mPackage.getPackageMajorVersion() << ","
216 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700217 out << "virtual const ::android::hardware::hidl_version&"
218 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200219 out.indent();
220 out << "return version;\n";
221 out.unindent();
222 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700223 out << "virtual bool isRemote() const override { return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800224
Andreas Huber881227d2016-08-02 14:20:21 -0700225 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700226 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700227
Andreas Huber881227d2016-08-02 14:20:21 -0700228 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800229 const TypedVar *elidedReturn = method->canElideCallback();
230
231 if (elidedReturn == nullptr && returnsValue) {
232 out << "using "
233 << method->name()
234 << "_cb = std::function<void("
235 << Method::GetArgSignature(method->results(),
236 true /* specify namespaces */)
237 << ")>;\n";
238 }
Andreas Huber881227d2016-08-02 14:20:21 -0700239
Andreas Huber3599d922016-08-09 10:42:57 -0700240 method->dumpAnnotations(out);
241
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700242 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700243 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700244 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700245 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700246 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700247 }
248
249 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700250 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700251 << Method::GetArgSignature(method->args(),
252 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700253
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700254 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700255 if (!method->args().empty()) {
256 out << ", ";
257 }
258
Steven Moreland67f67b42016-09-29 08:59:02 -0700259 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700260 }
261
Yifan Hong10fe0b52016-10-19 14:20:17 -0700262 out << ")";
263 if (method->isHidlReserved()) {
264 out << " override";
265 out << " {\n";
266 out.indent();
267 method->cppImpl(out);
268 out.unindent();
269 out << "\n}\n";
270 } else {
271 out << " = 0;\n";
272 }
Andreas Huber881227d2016-08-02 14:20:21 -0700273 }
Steven Moreland40786312016-08-16 10:29:40 -0700274
Yifan Hongfe95aa22016-10-19 17:26:45 -0700275 if (!iface->isRootType()) {
276 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700277 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700278
279 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700280 out << "static "
281 << childTypeResult
282 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700283 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700284 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700285 << ");\n";
286 }
287 }
288
Steven Morelandd39133b2016-11-11 12:30:08 -0800289 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700290
Steven Moreland0693f312016-11-09 15:06:14 -0800291 out << "DECLARE_SERVICE_MANAGER_INTERACTIONS(" << baseName << ")\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800292
293 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700294 }
295
296 if (isInterface) {
297 out.unindent();
298
Andreas Hubere3f769a2016-10-10 10:54:44 -0700299 out << "};\n\n";
300 }
301
302 err = mRootScope->emitGlobalTypeDeclarations(out);
303
304 if (err != OK) {
305 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700306 }
307
308 out << "\n";
309 enterLeaveNamespace(out, false /* enter */);
310
311 out << "\n#endif // " << guard << "\n";
312
313 return OK;
314}
315
Steven Moreland40786312016-08-16 10:29:40 -0700316status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
317 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800318 bool isInterface = AST::isInterface(&ifaceName);
319 const Interface *iface = nullptr;
320 std::string baseName{};
321 std::string klassName{};
322
323 if(isInterface) {
324 iface = mRootScope->getInterface();
325 baseName = iface->getBaseName();
326 klassName = "IHw" + baseName;
327 } else {
328 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700329 }
330
Steven Moreland40786312016-08-16 10:29:40 -0700331 std::string path = outputPath;
332 path.append(mCoordinator->convertPackageRootToPath(mPackage));
333 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
334 path.append(klassName + ".h");
335
Yifan Hong244e82d2016-11-11 11:13:57 -0800336 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700337
338 if (file == NULL) {
339 return -errno;
340 }
341
342 Formatter out(file);
343
344 const std::string guard = makeHeaderGuard(klassName);
345
346 out << "#ifndef " << guard << "\n";
347 out << "#define " << guard << "\n\n";
348
Yifan Hong244e82d2016-11-11 11:13:57 -0800349 if (isInterface) {
350 generateCppPackageInclude(out, mPackage, ifaceName);
351 } else {
352 generateCppPackageInclude(out, mPackage, "types");
353 }
Steven Moreland40786312016-08-16 10:29:40 -0700354
Steven Morelandee88eed2016-10-31 17:49:00 -0700355 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700356
357 for (const auto &item : mImportedNames) {
358 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800359 generateCppPackageInclude(out, item, "hwtypes");
360 } else {
361 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700362 }
Steven Moreland40786312016-08-16 10:29:40 -0700363 }
364
365 out << "\n";
366
Yifan Hong859e53f2016-11-14 19:08:24 -0800367 out << "#include <hidl/HidlTransportSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200368 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700369 out << "#include <hwbinder/IBinder.h>\n";
370 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700371
372 out << "\n";
373
374 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700375
Yifan Hong244e82d2016-11-11 11:13:57 -0800376 if (isInterface) {
377 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700378
Yifan Hong244e82d2016-11-11 11:13:57 -0800379 out << "struct "
380 << klassName
381 << " : public "
382 << ifaceName;
Steven Moreland40786312016-08-16 10:29:40 -0700383
Yifan Hong244e82d2016-11-11 11:13:57 -0800384 const Interface *superType = iface->superType();
Steven Moreland40786312016-08-16 10:29:40 -0700385
Yifan Hong244e82d2016-11-11 11:13:57 -0800386 out << ", public ::android::hardware::IInterface";
Steven Moreland40786312016-08-16 10:29:40 -0700387
Yifan Hong244e82d2016-11-11 11:13:57 -0800388 out << " {\n";
Steven Moreland40786312016-08-16 10:29:40 -0700389
Yifan Hong244e82d2016-11-11 11:13:57 -0800390 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700391
Yifan Hong244e82d2016-11-11 11:13:57 -0800392 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700393
Yifan Hong244e82d2016-11-11 11:13:57 -0800394 out.unindent();
395
396 out << "};\n\n";
397 }
398
399 status_t err = mRootScope->emitGlobalHwDeclarations(out);
400 if (err != OK) {
401 return err;
402 }
Steven Moreland40786312016-08-16 10:29:40 -0700403
404 enterLeaveNamespace(out, false /* enter */);
405
406 out << "\n#endif // " << guard << "\n";
407
408 return OK;
409}
410
Andreas Huber881227d2016-08-02 14:20:21 -0700411status_t AST::emitTypeDeclarations(Formatter &out) const {
412 return mRootScope->emitTypeDeclarations(out);
413}
414
Steven Morelanda7a421a2016-09-07 08:35:18 -0700415status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700416 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700417 out << "inline ";
418
Yifan Hong068c5522016-10-31 14:07:25 -0700419 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700420
421 const bool returnsValue = !method->results().empty();
422 const TypedVar *elidedReturn = method->canElideCallback();
423 out << " {\n";
424 out.indent();
425 out << "return mImpl->"
426 << method->name()
427 << "(";
428 bool first = true;
429 for (const auto &arg : method->args()) {
430 if (!first) {
431 out << ", ";
432 }
433 first = false;
434 out << arg->name();
435 }
436 if (returnsValue && elidedReturn == nullptr) {
437 if (!method->args().empty()) {
438 out << ", ";
439 }
440
441 out << "_hidl_cb";
442 }
443 out << ");\n";
444 out.unindent();
445 out << "}";
446
447 out << ";\n";
448
449 return OK;
450}
451
Steven Moreland69e7c702016-09-09 11:16:32 -0700452status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700453 const Method *method) const {
454 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700455
456 out << " {\n";
457 out.indent();
458
459 const bool returnsValue = !method->results().empty();
460 const TypedVar *elidedReturn = method->canElideCallback();
461
Steven Moreland67f67b42016-09-29 08:59:02 -0700462 if (returnsValue && elidedReturn == nullptr) {
463 generateCheckNonNull(out, "_hidl_cb");
464 }
465
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700466 generateCppInstrumentationCall(
467 out,
468 InstrumentationEvent::PASSTHROUGH_ENTRY,
469 method);
470
471 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700472
473 if (method->isOneway()) {
474 out << "addOnewayTask([this";
475 for (const auto &arg : method->args()) {
476 out << ", " << arg->name();
477 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700478 out << "] {\n";
479 out.indent();
480 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700481 }
482
483 out << "mImpl->"
484 << method->name()
485 << "(";
486
487 bool first = true;
488 for (const auto &arg : method->args()) {
489 if (!first) {
490 out << ", ";
491 }
492 first = false;
493 out << arg->name();
494 }
495 if (returnsValue && elidedReturn == nullptr) {
496 if (!method->args().empty()) {
497 out << ", ";
498 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800499 out << "[&](";
500 first = true;
501 for (const auto &arg : method->results()) {
502 if (!first) {
503 out << ", ";
504 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700505
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800506 out << "const auto &" << arg->name();
507
508 first = false;
509 }
510
511 out << ") {\n";
512 out.indent();
513 status_t status = generateCppInstrumentationCall(
514 out,
515 InstrumentationEvent::PASSTHROUGH_EXIT,
516 method);
517 if (status != OK) {
518 return status;
519 }
520
521 out << "_hidl_cb(";
522 first = true;
523 for (const auto &arg : method->results()) {
524 if (!first) {
525 out << ", ";
526 }
527
528 out << arg->name();
529
530 first = false;
531 }
532 out << ");\n";
533 out.unindent();
534 out << "});\n\n";
535 } else {
536 out << ");\n\n";
537 if (elidedReturn != nullptr) {
Steven Moreland90e50cd2016-11-22 13:36:36 -0800538 // Can get() without checking isOk() since we are checking the value
539 // returned by an in-process implementation.
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800540 out << elidedReturn->type().getCppResultType()
541 << " "
542 << elidedReturn->name()
Steven Moreland90e50cd2016-11-22 13:36:36 -0800543 << " = _hidl_return.get();\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800544 }
545 status_t status = generateCppInstrumentationCall(
546 out,
547 InstrumentationEvent::PASSTHROUGH_EXIT,
548 method);
549 if (status != OK) {
550 return status;
551 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700552 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700553
554 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700555 out.unindent();
556 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700557 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700558
559 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700560
561 out.unindent();
562 out << "}\n";
563
564 return OK;
565}
566
Yifan Hong068c5522016-10-31 14:07:25 -0700567status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700568
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700569 const Interface *iface = mRootScope->getInterface();
570
Yifan Hong10fe0b52016-10-19 14:20:17 -0700571 const Interface *prevIterface = nullptr;
572 for (const auto &tuple : iface->allMethodsFromRoot()) {
573 const Method *method = tuple.method();
574 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700575
Yifan Hong10fe0b52016-10-19 14:20:17 -0700576 if(prevIterface != superInterface) {
577 if (prevIterface != nullptr) {
578 out << "\n";
579 }
580 out << "// Methods from "
581 << superInterface->fullName()
582 << " follow.\n";
583 prevIterface = superInterface;
584 }
Yifan Hong068c5522016-10-31 14:07:25 -0700585 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700586
Yifan Hong10fe0b52016-10-19 14:20:17 -0700587 if (err != OK) {
588 return err;
589 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700590 }
591
Yifan Hong10fe0b52016-10-19 14:20:17 -0700592 out << "\n";
593
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700594 return OK;
595}
596
Andreas Huberb82318c2016-08-02 14:45:54 -0700597status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700598 std::string ifaceName;
599 if (!AST::isInterface(&ifaceName)) {
600 // types.hal does not get a stub header.
601 return OK;
602 }
603
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700604 const Interface *iface = mRootScope->getInterface();
605 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700606 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700607
Andreas Huberb82318c2016-08-02 14:45:54 -0700608 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700609 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700610 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700611 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700612 path.append(".h");
613
Andreas Huberd2943e12016-08-05 11:59:31 -0700614 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700615 FILE *file = fopen(path.c_str(), "w");
616
617 if (file == NULL) {
618 return -errno;
619 }
620
621 Formatter out(file);
622
Steven Moreland40786312016-08-16 10:29:40 -0700623 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700624
625 out << "#ifndef " << guard << "\n";
626 out << "#define " << guard << "\n\n";
627
Steven Morelandee88eed2016-10-31 17:49:00 -0700628 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
629 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700630
631 enterLeaveNamespace(out, true /* enter */);
632 out << "\n";
633
634 out << "struct "
635 << "Bn"
636 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700637 << " : public ::android::hardware::BnInterface<I"
638 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700639 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700640
641 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700642 out << "explicit Bn"
643 << baseName
644 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
645 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700646 out << "::android::status_t onTransact(\n";
647 out.indent();
648 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700649 out << "uint32_t _hidl_code,\n";
650 out << "const ::android::hardware::Parcel &_hidl_data,\n";
651 out << "::android::hardware::Parcel *_hidl_reply,\n";
652 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700653 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700654 out.unindent();
655 out.unindent();
656
Yifan Hong068c5522016-10-31 14:07:25 -0700657 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
658 return generateStubMethod(out, method);
659 });
Steven Moreland9c387612016-09-07 09:54:26 -0700660
661 if (err != OK) {
662 return err;
663 }
664
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700665
Andreas Huber881227d2016-08-02 14:20:21 -0700666 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700667 out << "};\n\n";
668
669 enterLeaveNamespace(out, false /* enter */);
670
671 out << "\n#endif // " << guard << "\n";
672
673 return OK;
674}
675
Andreas Huberb82318c2016-08-02 14:45:54 -0700676status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700677 std::string ifaceName;
678 if (!AST::isInterface(&ifaceName)) {
679 // types.hal does not get a proxy header.
680 return OK;
681 }
682
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700683 const Interface *iface = mRootScope->getInterface();
684 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700685
Andreas Huberb82318c2016-08-02 14:45:54 -0700686 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700687 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700688 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700689 path.append("Bp");
690 path.append(baseName);
691 path.append(".h");
692
Andreas Huberd2943e12016-08-05 11:59:31 -0700693 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700694 FILE *file = fopen(path.c_str(), "w");
695
696 if (file == NULL) {
697 return -errno;
698 }
699
700 Formatter out(file);
701
702 const std::string guard = makeHeaderGuard("Bp" + baseName);
703
704 out << "#ifndef " << guard << "\n";
705 out << "#define " << guard << "\n\n";
706
707 std::vector<std::string> packageComponents;
708 getPackageAndVersionComponents(
709 &packageComponents, false /* cpp_compatible */);
710
Steven Morelandee88eed2016-10-31 17:49:00 -0700711 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
712 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700713
714 enterLeaveNamespace(out, true /* enter */);
715 out << "\n";
716
717 out << "struct "
718 << "Bp"
719 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700720 << " : public ::android::hardware::BpInterface<IHw"
721 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700722 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700723
724 out.indent();
725
726 out << "explicit Bp"
727 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700728 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700729 << "\n\n";
730
Yifan Hong10fe0b52016-10-19 14:20:17 -0700731 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700732
Yifan Hong068c5522016-10-31 14:07:25 -0700733 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
734 method->generateCppSignature(out);
735 out << " override;\n";
736 return OK;
737 });
Steven Moreland9c387612016-09-07 09:54:26 -0700738
739 if (err != OK) {
740 return err;
741 }
Andreas Huber881227d2016-08-02 14:20:21 -0700742
743 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700744 out << "};\n\n";
745
746 enterLeaveNamespace(out, false /* enter */);
747
748 out << "\n#endif // " << guard << "\n";
749
750 return OK;
751}
752
Andreas Huberb82318c2016-08-02 14:45:54 -0700753status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700754
Andreas Huberb82318c2016-08-02 14:45:54 -0700755 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700756 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700757 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700758
759 std::string ifaceName;
760 std::string baseName;
761
Yifan Hongfe95aa22016-10-19 17:26:45 -0700762 const Interface *iface = nullptr;
763 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700764 if (!AST::isInterface(&ifaceName)) {
765 baseName = "types";
766 isInterface = false;
767 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700768 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700769 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700770 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700771 }
772
773 path.append(baseName);
774
775 if (baseName != "types") {
776 path.append("All");
777 }
778
779 path.append(".cpp");
780
Andreas Huberd2943e12016-08-05 11:59:31 -0700781 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700782 FILE *file = fopen(path.c_str(), "w");
783
784 if (file == NULL) {
785 return -errno;
786 }
787
788 Formatter out(file);
789
Steven Moreland05cd4232016-11-21 16:01:12 -0800790 out << "#include <android/log.h>\n";
Martijn Coenen7b295242016-11-04 16:52:56 +0100791 out << "#include <cutils/trace.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700792 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700793 // This is a no-op for IServiceManager itself.
794 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
795
Steven Morelandee88eed2016-10-31 17:49:00 -0700796 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
797 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
798 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700799
800 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700801 generateCppPackageInclude(out,
802 superType->fqName(),
803 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700804 }
Andreas Huber881227d2016-08-02 14:20:21 -0700805 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700806 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800807 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700808 }
809
810 out << "\n";
811
812 enterLeaveNamespace(out, true /* enter */);
813 out << "\n";
814
815 status_t err = generateTypeSource(out, ifaceName);
816
817 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700818 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700819 out << "constexpr ::android::hardware::hidl_version "
820 << ifaceName
821 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700822
823 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800824 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700825 << iface->getBaseName()
826 << "::descriptor(\""
827 << iface->fqName().string()
828 << "\");\n\n";
829
Yifan Hong158655a2016-11-08 12:34:07 -0800830 out << "int I"
831 << iface->getBaseName()
832 << "::hidlStaticBlock = []() -> int {\n";
833 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800834 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800835 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800836 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800837 out.indentBlock(2, [&] {
838 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
839 out.indentBlock([&] {
840 out << "return new Bn"
841 << iface->getBaseName()
842 << "(reinterpret_cast<I"
843 << iface->getBaseName()
844 << " *>(iIntf));\n";
845 });
846 out << "};\n";
847 });
848 out << "return 1;\n";
849 });
850 out << "}();\n\n";
851
Yifan Hongfe95aa22016-10-19 17:26:45 -0700852 err = generateInterfaceSource(out);
853 }
854
855 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700856 err = generateProxySource(out, baseName);
857 }
858
859 if (err == OK && isInterface) {
860 err = generateStubSource(out, baseName);
861 }
862
Steven Moreland40786312016-08-16 10:29:40 -0700863 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700864 err = generatePassthroughSource(out);
865 }
866
867 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700868 const Interface *iface = mRootScope->getInterface();
869
Steven Moreland0693f312016-11-09 15:06:14 -0800870 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
Steven Moreland9c387612016-09-07 09:54:26 -0700871 << baseName << ", "
872 << "\"" << iface->fqName().package()
Steven Moreland7e367bf2016-11-04 11:31:41 -0700873 << iface->fqName().atVersion()
874 << "\")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700875 }
876
Andreas Huber881227d2016-08-02 14:20:21 -0700877 enterLeaveNamespace(out, false /* enter */);
878
879 return err;
880}
881
Steven Moreland67f67b42016-09-29 08:59:02 -0700882// static
883void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
884 out << "if (" << nonNull << " == nullptr) {\n";
885 out.indent();
886 out << "return ::android::hardware::Status::fromExceptionCode(\n";
887 out.indent();
888 out.indent();
889 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
890 out.unindent();
891 out.unindent();
892 out.unindent();
893 out << "}\n\n";
894}
895
Andreas Huber881227d2016-08-02 14:20:21 -0700896status_t AST::generateTypeSource(
897 Formatter &out, const std::string &ifaceName) const {
898 return mRootScope->emitTypeDefinitions(out, ifaceName);
899}
900
Andreas Hubere7ff2282016-08-16 13:50:03 -0700901void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700902 Formatter &out,
903 const std::vector<TypedVar *> &args,
904 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700905 if (args.empty()) {
906 return;
907 }
908
909 for (const auto &arg : args) {
910 const Type &type = arg->type();
911
Yifan Hong3b320f82016-11-01 15:15:54 -0700912 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700913 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700914 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700915 << ";\n";
916 }
917
918 out << "\n";
919}
920
Andreas Huber881227d2016-08-02 14:20:21 -0700921void AST::emitCppReaderWriter(
922 Formatter &out,
923 const std::string &parcelObj,
924 bool parcelObjIsPointer,
925 const TypedVar *arg,
926 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700927 Type::ErrorMode mode,
928 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700929 const Type &type = arg->type();
930
Andreas Huber881227d2016-08-02 14:20:21 -0700931 type.emitReaderWriter(
932 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700933 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700934 parcelObj,
935 parcelObjIsPointer,
936 isReader,
937 mode);
938}
939
Yifan Hongbf459bc2016-08-23 16:50:37 -0700940void AST::emitCppResolveReferences(
941 Formatter &out,
942 const std::string &parcelObj,
943 bool parcelObjIsPointer,
944 const TypedVar *arg,
945 bool isReader,
946 Type::ErrorMode mode,
947 bool addPrefixToName) const {
948 const Type &type = arg->type();
949 if(type.needsResolveReferences()) {
950 type.emitResolveReferences(
951 out,
952 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
953 isReader, // nameIsPointer
954 parcelObj,
955 parcelObjIsPointer,
956 isReader,
957 mode);
958 }
959}
960
Yifan Hong068c5522016-10-31 14:07:25 -0700961status_t AST::generateProxyMethodSource(Formatter &out,
962 const std::string &klassName,
963 const Method *method,
964 const Interface *superInterface) const {
965
966 method->generateCppSignature(out,
967 klassName,
968 true /* specify namespaces */);
969
970 const bool returnsValue = !method->results().empty();
971 const TypedVar *elidedReturn = method->canElideCallback();
972
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800973 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700974
975 out.indent();
976
977 if (returnsValue && elidedReturn == nullptr) {
978 generateCheckNonNull(out, "_hidl_cb");
979 }
980
981 status_t status = generateCppInstrumentationCall(
982 out,
983 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700984 method);
985 if (status != OK) {
986 return status;
987 }
988
989 out << "::android::hardware::Parcel _hidl_data;\n";
990 out << "::android::hardware::Parcel _hidl_reply;\n";
991 out << "::android::status_t _hidl_err;\n";
992 out << "::android::hardware::Status _hidl_status;\n\n";
993
994 declareCppReaderLocals(
995 out, method->results(), true /* forResults */);
996
997 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandd39133b2016-11-11 12:30:08 -0800998 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800999 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -08001000 } else {
1001 out << superInterface->fqName().cppNamespace()
1002 << "::I"
1003 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001004 }
1005 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001006 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1007
1008 // First DFS: write all buffers and resolve pointers for parent
1009 for (const auto &arg : method->args()) {
1010 emitCppReaderWriter(
1011 out,
1012 "_hidl_data",
1013 false /* parcelObjIsPointer */,
1014 arg,
1015 false /* reader */,
1016 Type::ErrorMode_Goto,
1017 false /* addPrefixToName */);
1018 }
1019
1020 // Second DFS: resolve references.
1021 for (const auto &arg : method->args()) {
1022 emitCppResolveReferences(
1023 out,
1024 "_hidl_data",
1025 false /* parcelObjIsPointer */,
1026 arg,
1027 false /* reader */,
1028 Type::ErrorMode_Goto,
1029 false /* addPrefixToName */);
1030 }
1031
1032 out << "_hidl_err = remote()->transact("
1033 << method->getSerialId()
1034 << " /* "
1035 << method->name()
1036 << " */, _hidl_data, &_hidl_reply";
1037
1038 if (method->isOneway()) {
1039 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1040 }
1041 out << ");\n";
1042
1043 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1044
1045 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001046 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001047 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1048 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1049
1050
1051 // First DFS: write all buffers and resolve pointers for parent
1052 for (const auto &arg : method->results()) {
1053 emitCppReaderWriter(
1054 out,
1055 "_hidl_reply",
1056 false /* parcelObjIsPointer */,
1057 arg,
1058 true /* reader */,
1059 Type::ErrorMode_Goto,
1060 true /* addPrefixToName */);
1061 }
1062
1063 // Second DFS: resolve references.
1064 for (const auto &arg : method->results()) {
1065 emitCppResolveReferences(
1066 out,
1067 "_hidl_reply",
1068 false /* parcelObjIsPointer */,
1069 arg,
1070 true /* reader */,
1071 Type::ErrorMode_Goto,
1072 true /* addPrefixToName */);
1073 }
1074
1075 if (returnsValue && elidedReturn == nullptr) {
1076 out << "_hidl_cb(";
1077
1078 bool first = true;
1079 for (const auto &arg : method->results()) {
1080 if (!first) {
1081 out << ", ";
1082 }
1083
1084 if (arg->type().resultNeedsDeref()) {
1085 out << "*";
1086 }
1087 out << "_hidl_out_" << arg->name();
1088
1089 first = false;
1090 }
1091
1092 out << ");\n\n";
1093 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001094 }
1095 status = generateCppInstrumentationCall(
1096 out,
1097 InstrumentationEvent::CLIENT_API_EXIT,
1098 method);
1099 if (status != OK) {
1100 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001101 }
1102
1103 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001104 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1105 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001106 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001107 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1108 } else {
1109 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1110 out << "return ::android::hardware::Return<void>();\n\n";
1111 }
1112
1113 out.unindent();
1114 out << "_hidl_error:\n";
1115 out.indent();
1116 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1117 out << "return ::android::hardware::Return<";
1118 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001119 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001120 } else {
1121 out << "void";
1122 }
1123 out << ">(_hidl_status);\n";
1124
1125 out.unindent();
1126 out << "}\n\n";
1127 return OK;
1128}
1129
Andreas Huber881227d2016-08-02 14:20:21 -07001130status_t AST::generateProxySource(
1131 Formatter &out, const std::string &baseName) const {
1132 const std::string klassName = "Bp" + baseName;
1133
1134 out << klassName
1135 << "::"
1136 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001137 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001138
1139 out.indent();
1140 out.indent();
1141
1142 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001143 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001144 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001145 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001146 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001147 << mPackage.string()
1148 << "::I"
1149 << baseName
1150 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001151
Andreas Huber881227d2016-08-02 14:20:21 -07001152 out.unindent();
1153 out.unindent();
1154 out << "}\n\n";
1155
Yifan Hong068c5522016-10-31 14:07:25 -07001156 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1157 return generateProxyMethodSource(out, klassName, method, superInterface);
1158 });
Andreas Huber881227d2016-08-02 14:20:21 -07001159
Yifan Hong068c5522016-10-31 14:07:25 -07001160 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001161}
1162
1163status_t AST::generateStubSource(
1164 Formatter &out, const std::string &baseName) const {
1165 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1166 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001167 << ", "
1168 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001169 << "::I"
1170 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001171 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001172
1173 const std::string klassName = "Bn" + baseName;
1174
Steven Moreland40786312016-08-16 10:29:40 -07001175 out << klassName
1176 << "::"
1177 << klassName
1178 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1179
1180 out.indent();
1181 out.indent();
1182
1183 out << ": BnInterface"
1184 << "<I"
1185 << baseName
1186 << ", IHw"
1187 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001188 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001189 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001190 << mPackage.string()
1191 << "::I"
1192 << baseName
1193 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001194
1195 out.unindent();
1196 out.unindent();
1197 out << "}\n\n";
1198
Andreas Huber881227d2016-08-02 14:20:21 -07001199 out << "::android::status_t " << klassName << "::onTransact(\n";
1200
1201 out.indent();
1202 out.indent();
1203
Iliyan Malchev549e2592016-08-10 08:59:12 -07001204 out << "uint32_t _hidl_code,\n"
1205 << "const ::android::hardware::Parcel &_hidl_data,\n"
1206 << "::android::hardware::Parcel *_hidl_reply,\n"
1207 << "uint32_t _hidl_flags,\n"
1208 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001209
1210 out.unindent();
1211
Iliyan Malchev549e2592016-08-10 08:59:12 -07001212 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001213 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001214 out.indent();
1215
1216 const Interface *iface = mRootScope->getInterface();
1217
Yifan Hong10fe0b52016-10-19 14:20:17 -07001218 for (const auto &tuple : iface->allMethodsFromRoot()) {
1219 const Method *method = tuple.method();
1220 const Interface *superInterface = tuple.interface();
1221 out << "case "
1222 << method->getSerialId()
1223 << " /* "
1224 << method->name()
1225 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001226
Yifan Hong10fe0b52016-10-19 14:20:17 -07001227 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001228
Yifan Hong10fe0b52016-10-19 14:20:17 -07001229 status_t err =
1230 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001231
Yifan Hong10fe0b52016-10-19 14:20:17 -07001232 if (err != OK) {
1233 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001234 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001235
1236 out.unindent();
1237 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001238 }
1239
1240 out << "default:\n{\n";
1241 out.indent();
1242
Andreas Huber8a82ff72016-08-04 10:29:39 -07001243 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001244 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001245 << ">::onTransact(\n";
1246
1247 out.indent();
1248 out.indent();
1249
Iliyan Malchev549e2592016-08-10 08:59:12 -07001250 out << "_hidl_code, _hidl_data, _hidl_reply, "
1251 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001252
1253 out.unindent();
1254 out.unindent();
1255
1256 out.unindent();
1257 out << "}\n";
1258
1259 out.unindent();
1260 out << "}\n\n";
1261
Iliyan Malchev549e2592016-08-10 08:59:12 -07001262 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001263 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001264 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001265 out.indent();
1266 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001267 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1268 out << "_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001269 out.unindent();
1270 out.unindent();
1271
1272 out.unindent();
1273 out << "}\n\n";
1274
Iliyan Malchev549e2592016-08-10 08:59:12 -07001275 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001276
1277 out.unindent();
1278 out << "}\n\n";
1279
1280 return OK;
1281}
1282
1283status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001284 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001285 out << "if (!_hidl_data.enforceInterface(";
1286
Steven Morelandd39133b2016-11-11 12:30:08 -08001287 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -08001288 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -08001289 } else {
1290 out << iface->fqName().cppNamespace()
1291 << "::I"
1292 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001293 }
1294
1295 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001296
Andreas Huber881227d2016-08-02 14:20:21 -07001297 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001298 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001299 out << "break;\n";
1300 out.unindent();
1301 out << "}\n\n";
1302
Andreas Huber5e44a292016-09-27 14:52:39 -07001303 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001304
Yifan Hongbf459bc2016-08-23 16:50:37 -07001305 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001306 for (const auto &arg : method->args()) {
1307 emitCppReaderWriter(
1308 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001309 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001310 false /* parcelObjIsPointer */,
1311 arg,
1312 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001313 Type::ErrorMode_Break,
1314 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001315 }
1316
Yifan Hongbf459bc2016-08-23 16:50:37 -07001317 // Second DFS: resolve references
1318 for (const auto &arg : method->args()) {
1319 emitCppResolveReferences(
1320 out,
1321 "_hidl_data",
1322 false /* parcelObjIsPointer */,
1323 arg,
1324 true /* reader */,
1325 Type::ErrorMode_Break,
1326 false /* addPrefixToName */);
1327 }
1328
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001329 status_t status = generateCppInstrumentationCall(
1330 out,
1331 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001332 method);
1333 if (status != OK) {
1334 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001335 }
1336
Andreas Huber881227d2016-08-02 14:20:21 -07001337 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001338 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001339
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001340 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001341 out << elidedReturn->type().getCppResultType()
1342 << " "
1343 << elidedReturn->name()
1344 << " = "
1345 << method->name()
1346 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001347
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001348 bool first = true;
1349 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001350 if (!first) {
1351 out << ", ";
1352 }
1353
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001354 if (arg->type().resultNeedsDeref()) {
1355 out << "*";
1356 }
1357
1358 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001359
1360 first = false;
1361 }
1362
Steven Moreland90e50cd2016-11-22 13:36:36 -08001363 // Can get() without checking isOk() since we are checking the value
1364 // returned by an in-process implementation.
1365 out << ").get();\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001366 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1367 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001368
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001369 elidedReturn->type().emitReaderWriter(
1370 out,
1371 elidedReturn->name(),
1372 "_hidl_reply",
1373 true, /* parcelObjIsPointer */
1374 false, /* isReader */
1375 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001376
Yifan Hongbf459bc2016-08-23 16:50:37 -07001377 emitCppResolveReferences(
1378 out,
1379 "_hidl_reply",
1380 true /* parcelObjIsPointer */,
1381 elidedReturn,
1382 false /* reader */,
1383 Type::ErrorMode_Ignore,
1384 false /* addPrefixToName */);
1385
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001386 status_t status = generateCppInstrumentationCall(
1387 out,
1388 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001389 method);
1390 if (status != OK) {
1391 return status;
1392 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001393
Iliyan Malchev549e2592016-08-10 08:59:12 -07001394 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001395 } else {
1396 if (returnsValue) {
1397 out << "bool _hidl_callbackCalled = false;\n\n";
1398 }
Andreas Huber881227d2016-08-02 14:20:21 -07001399
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001400 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001401
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001402 bool first = true;
1403 for (const auto &arg : method->args()) {
1404 if (!first) {
1405 out << ", ";
1406 }
Andreas Huber881227d2016-08-02 14:20:21 -07001407
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001408 if (arg->type().resultNeedsDeref()) {
1409 out << "*";
1410 }
1411
1412 out << arg->name();
1413
1414 first = false;
1415 }
1416
1417 if (returnsValue) {
1418 if (!first) {
1419 out << ", ";
1420 }
1421
1422 out << "[&](";
1423
1424 first = true;
1425 for (const auto &arg : method->results()) {
1426 if (!first) {
1427 out << ", ";
1428 }
1429
1430 out << "const auto &" << arg->name();
1431
1432 first = false;
1433 }
1434
1435 out << ") {\n";
1436 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001437 out << "if (_hidl_callbackCalled) {\n";
1438 out.indent();
1439 out << "LOG_ALWAYS_FATAL(\""
1440 << method->name()
1441 << ": _hidl_cb called a second time, but must be called once.\");\n";
1442 out.unindent();
1443 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001444 out << "_hidl_callbackCalled = true;\n\n";
1445
Yifan Hong859e53f2016-11-14 19:08:24 -08001446 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1447 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001448
Yifan Hongbf459bc2016-08-23 16:50:37 -07001449 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001450 for (const auto &arg : method->results()) {
1451 emitCppReaderWriter(
1452 out,
1453 "_hidl_reply",
1454 true /* parcelObjIsPointer */,
1455 arg,
1456 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001457 Type::ErrorMode_Ignore,
1458 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001459 }
1460
Yifan Hongbf459bc2016-08-23 16:50:37 -07001461 // Second DFS: resolve references
1462 for (const auto &arg : method->results()) {
1463 emitCppResolveReferences(
1464 out,
1465 "_hidl_reply",
1466 true /* parcelObjIsPointer */,
1467 arg,
1468 false /* reader */,
1469 Type::ErrorMode_Ignore,
1470 false /* addPrefixToName */);
1471 }
1472
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001473 status_t status = generateCppInstrumentationCall(
1474 out,
1475 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001476 method);
1477 if (status != OK) {
1478 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001479 }
1480
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001481 out << "_hidl_cb(*_hidl_reply);\n";
1482
1483 out.unindent();
1484 out << "}\n";
1485 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001486 out << ");\n\n";
1487
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001488 if (returnsValue) {
1489 out << "if (!_hidl_callbackCalled) {\n";
1490 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001491 out << "LOG_ALWAYS_FATAL(\""
1492 << method->name()
1493 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001494 out.unindent();
1495 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001496 } else {
1497 out << "::android::hardware::writeToParcel("
1498 << "::android::hardware::Status::ok(), "
1499 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001500 }
Andreas Huber881227d2016-08-02 14:20:21 -07001501 }
1502
1503 out << "break;\n";
1504
1505 return OK;
1506}
1507
Steven Moreland69e7c702016-09-09 11:16:32 -07001508status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1509 std::string ifaceName;
1510 if (!AST::isInterface(&ifaceName)) {
1511 // types.hal does not get a stub header.
1512 return OK;
1513 }
1514
1515 const Interface *iface = mRootScope->getInterface();
1516
1517 const std::string baseName = iface->getBaseName();
1518 const std::string klassName = "Bs" + baseName;
1519
1520 bool supportOneway = iface->hasOnewayMethods();
1521
1522 std::string path = outputPath;
1523 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1524 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1525 path.append(klassName);
1526 path.append(".h");
1527
1528 CHECK(Coordinator::MakeParentHierarchy(path));
1529 FILE *file = fopen(path.c_str(), "w");
1530
1531 if (file == NULL) {
1532 return -errno;
1533 }
1534
1535 Formatter out(file);
1536
1537 const std::string guard = makeHeaderGuard(klassName);
1538
1539 out << "#ifndef " << guard << "\n";
1540 out << "#define " << guard << "\n\n";
1541
1542 std::vector<std::string> packageComponents;
1543 getPackageAndVersionComponents(
1544 &packageComponents, false /* cpp_compatible */);
1545
1546 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001547
1548 generateCppPackageInclude(out, mPackage, ifaceName);
1549 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001550
1551 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001552 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001553 }
1554
1555 enterLeaveNamespace(out, true /* enter */);
1556 out << "\n";
1557
1558 out << "struct "
1559 << klassName
1560 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001561 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001562
1563 out.indent();
1564 out << "explicit "
1565 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001566 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001567 << ifaceName
1568 << "> impl);\n";
1569
Yifan Hong068c5522016-10-31 14:07:25 -07001570 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1571 return generatePassthroughMethod(out, method);
1572 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001573
1574 if (err != OK) {
1575 return err;
1576 }
1577
1578 out.unindent();
1579 out << "private:\n";
1580 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001581 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001582
1583 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001584 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001585
1586 out << "\n";
1587
1588 out << "::android::hardware::Return<void> addOnewayTask("
1589 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001590 }
1591
1592 out.unindent();
1593
1594 out << "};\n\n";
1595
1596 enterLeaveNamespace(out, false /* enter */);
1597
1598 out << "\n#endif // " << guard << "\n";
1599
1600 return OK;
1601}
1602
Yifan Hongfe95aa22016-10-19 17:26:45 -07001603status_t AST::generateInterfaceSource(Formatter &out) const {
1604 const Interface *iface = mRootScope->getInterface();
1605
Yifan Hong2d7126b2016-10-20 15:12:57 -07001606 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001607 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001608 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001609
1610 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001611 out << "// static \n"
1612 << childTypeResult
1613 << " I"
1614 << iface->getBaseName()
1615 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001616 << superType->getCppArgumentType()
1617 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001618 out.indent();
1619 out << "return ::android::hardware::castInterface<";
1620 out << "I" << iface->getBaseName() << ", "
1621 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001622 << "Bp" << iface->getBaseName() << ", "
1623 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001624 << ">(\n";
1625 out.indent();
1626 out.indent();
1627 out << "parent, \""
1628 << iface->fqName().string()
1629 << "\");\n";
1630 out.unindent();
1631 out.unindent();
1632 out.unindent();
1633 out << "}\n\n";
1634 }
1635 }
1636
1637 return OK;
1638}
1639
Steven Moreland69e7c702016-09-09 11:16:32 -07001640status_t AST::generatePassthroughSource(Formatter &out) const {
1641 const Interface *iface = mRootScope->getInterface();
1642
1643 const std::string baseName = iface->getBaseName();
1644 const std::string klassName = "Bs" + baseName;
1645
1646 out << klassName
1647 << "::"
1648 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001649 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001650 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001651 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001652 << iface->fqName().string()
1653 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001654 if (iface->hasOnewayMethods()) {
1655 out << "\n";
1656 out.indentBlock([&] {
1657 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1658 });
1659 }
1660 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001661
1662 if (iface->hasOnewayMethods()) {
1663 out << "::android::hardware::Return<void> "
1664 << klassName
1665 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1666 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001667 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001668 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001669 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1670 out.indent();
1671 out.indent();
1672 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1673 out.unindent();
1674 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001675 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001676 out << "}\n";
1677
Steven Morelandd366c262016-10-11 15:29:10 -07001678 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001679
1680 out.unindent();
1681 out << "}\n\n";
1682
1683
1684 }
1685
1686 return OK;
1687}
1688
Martijn Coenen7b295242016-11-04 16:52:56 +01001689status_t AST::generateCppAtraceCall(Formatter &out,
1690 InstrumentationEvent event,
1691 const Method *method) const {
1692 const Interface *iface = mRootScope->getInterface();
1693 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1694 switch (event) {
1695 case SERVER_API_ENTRY:
1696 {
1697 out << "atrace_begin(ATRACE_TAG_HAL, \""
1698 << baseString + "::server\");\n";
1699 break;
1700 }
1701 case CLIENT_API_ENTRY:
1702 {
1703 out << "atrace_begin(ATRACE_TAG_HAL, \""
1704 << baseString + "::client\");\n";
1705 break;
1706 }
1707 case PASSTHROUGH_ENTRY:
1708 {
1709 out << "atrace_begin(ATRACE_TAG_HAL, \""
1710 << baseString + "::passthrough\");\n";
1711 break;
1712 }
1713 case SERVER_API_EXIT:
1714 case CLIENT_API_EXIT:
1715 case PASSTHROUGH_EXIT:
1716 {
1717 out << "atrace_end(ATRACE_TAG_HAL);\n";
1718 break;
1719 }
1720 default:
1721 {
1722 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1723 return UNKNOWN_ERROR;
1724 }
1725 }
1726
1727 return OK;
1728}
1729
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001730status_t AST::generateCppInstrumentationCall(
1731 Formatter &out,
1732 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001733 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001734 status_t err = generateCppAtraceCall(out, event, method);
1735 if (err != OK) {
1736 return err;
1737 }
1738
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001739 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1740 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001741 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001742 std::string event_str = "";
1743 switch (event) {
1744 case SERVER_API_ENTRY:
1745 {
1746 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1747 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001748 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001749 << (arg->type().resultNeedsDeref() ? "" : "&")
1750 << arg->name()
1751 << ");\n";
1752 }
1753 break;
1754 }
1755 case SERVER_API_EXIT:
1756 {
1757 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001758 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001759 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001760 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001761 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001762 }
1763 break;
1764 }
1765 case CLIENT_API_ENTRY:
1766 {
1767 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1768 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001769 out << "_hidl_args.push_back((void *)&"
1770 << arg->name()
1771 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001772 }
1773 break;
1774 }
1775 case CLIENT_API_EXIT:
1776 {
1777 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1778 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001779 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001780 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001781 << "_hidl_out_"
1782 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001783 << ");\n";
1784 }
1785 break;
1786 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001787 case PASSTHROUGH_ENTRY:
1788 {
1789 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1790 for (const auto &arg : method->args()) {
1791 out << "_hidl_args.push_back((void *)&"
1792 << arg->name()
1793 << ");\n";
1794 }
1795 break;
1796 }
1797 case PASSTHROUGH_EXIT:
1798 {
1799 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001800 for (const auto &arg : method->results()) {
1801 out << "_hidl_args.push_back((void *)&"
1802 << arg->name()
1803 << ");\n";
1804 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001805 break;
1806 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001807 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001808 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001809 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001810 return UNKNOWN_ERROR;
1811 }
1812 }
1813
Steven Moreland031ccf12016-10-31 15:54:38 -07001814 const Interface *iface = mRootScope->getInterface();
1815
Steven Moreland1ab31442016-11-03 18:37:51 -07001816 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001817 out.indent();
1818 out << "callback("
1819 << event_str
1820 << ", \""
1821 << mPackage.package()
1822 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001823 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001824 << "\", \""
1825 << iface->localName()
1826 << "\", \""
1827 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001828 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001829 out.unindent();
1830 out << "}\n";
1831 out.unindent();
1832 out << "}\n\n";
1833
1834 return OK;
1835}
1836
Andreas Huber881227d2016-08-02 14:20:21 -07001837} // namespace android
1838