blob: c9683b2613ffd94fb9f5f3ee3b1f3db19d74a560 [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) {
538 out << elidedReturn->type().getCppResultType()
539 << " "
540 << elidedReturn->name()
541 << " = _hidl_return;\n";
542 }
543 status_t status = generateCppInstrumentationCall(
544 out,
545 InstrumentationEvent::PASSTHROUGH_EXIT,
546 method);
547 if (status != OK) {
548 return status;
549 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700550 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700551
552 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700553 out.unindent();
554 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700555 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700556
557 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700558
559 out.unindent();
560 out << "}\n";
561
562 return OK;
563}
564
Yifan Hong068c5522016-10-31 14:07:25 -0700565status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700566
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700567 const Interface *iface = mRootScope->getInterface();
568
Yifan Hong10fe0b52016-10-19 14:20:17 -0700569 const Interface *prevIterface = nullptr;
570 for (const auto &tuple : iface->allMethodsFromRoot()) {
571 const Method *method = tuple.method();
572 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700573
Yifan Hong10fe0b52016-10-19 14:20:17 -0700574 if(prevIterface != superInterface) {
575 if (prevIterface != nullptr) {
576 out << "\n";
577 }
578 out << "// Methods from "
579 << superInterface->fullName()
580 << " follow.\n";
581 prevIterface = superInterface;
582 }
Yifan Hong068c5522016-10-31 14:07:25 -0700583 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700584
Yifan Hong10fe0b52016-10-19 14:20:17 -0700585 if (err != OK) {
586 return err;
587 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700588 }
589
Yifan Hong10fe0b52016-10-19 14:20:17 -0700590 out << "\n";
591
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700592 return OK;
593}
594
Andreas Huberb82318c2016-08-02 14:45:54 -0700595status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700596 std::string ifaceName;
597 if (!AST::isInterface(&ifaceName)) {
598 // types.hal does not get a stub header.
599 return OK;
600 }
601
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700602 const Interface *iface = mRootScope->getInterface();
603 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700604 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700605
Andreas Huberb82318c2016-08-02 14:45:54 -0700606 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700607 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700608 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700609 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700610 path.append(".h");
611
Andreas Huberd2943e12016-08-05 11:59:31 -0700612 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700613 FILE *file = fopen(path.c_str(), "w");
614
615 if (file == NULL) {
616 return -errno;
617 }
618
619 Formatter out(file);
620
Steven Moreland40786312016-08-16 10:29:40 -0700621 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700622
623 out << "#ifndef " << guard << "\n";
624 out << "#define " << guard << "\n\n";
625
Steven Morelandee88eed2016-10-31 17:49:00 -0700626 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
627 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700628
629 enterLeaveNamespace(out, true /* enter */);
630 out << "\n";
631
632 out << "struct "
633 << "Bn"
634 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700635 << " : public ::android::hardware::BnInterface<I"
636 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700637 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700638
639 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700640 out << "explicit Bn"
641 << baseName
642 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
643 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700644 out << "::android::status_t onTransact(\n";
645 out.indent();
646 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700647 out << "uint32_t _hidl_code,\n";
648 out << "const ::android::hardware::Parcel &_hidl_data,\n";
649 out << "::android::hardware::Parcel *_hidl_reply,\n";
650 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700651 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700652 out.unindent();
653 out.unindent();
654
Yifan Hong068c5522016-10-31 14:07:25 -0700655 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
656 return generateStubMethod(out, method);
657 });
Steven Moreland9c387612016-09-07 09:54:26 -0700658
659 if (err != OK) {
660 return err;
661 }
662
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700663
Andreas Huber881227d2016-08-02 14:20:21 -0700664 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700665 out << "};\n\n";
666
667 enterLeaveNamespace(out, false /* enter */);
668
669 out << "\n#endif // " << guard << "\n";
670
671 return OK;
672}
673
Andreas Huberb82318c2016-08-02 14:45:54 -0700674status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700675 std::string ifaceName;
676 if (!AST::isInterface(&ifaceName)) {
677 // types.hal does not get a proxy header.
678 return OK;
679 }
680
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700681 const Interface *iface = mRootScope->getInterface();
682 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700683
Andreas Huberb82318c2016-08-02 14:45:54 -0700684 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700685 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700686 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700687 path.append("Bp");
688 path.append(baseName);
689 path.append(".h");
690
Andreas Huberd2943e12016-08-05 11:59:31 -0700691 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700692 FILE *file = fopen(path.c_str(), "w");
693
694 if (file == NULL) {
695 return -errno;
696 }
697
698 Formatter out(file);
699
700 const std::string guard = makeHeaderGuard("Bp" + baseName);
701
702 out << "#ifndef " << guard << "\n";
703 out << "#define " << guard << "\n\n";
704
705 std::vector<std::string> packageComponents;
706 getPackageAndVersionComponents(
707 &packageComponents, false /* cpp_compatible */);
708
Steven Morelandee88eed2016-10-31 17:49:00 -0700709 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
710 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700711
712 enterLeaveNamespace(out, true /* enter */);
713 out << "\n";
714
715 out << "struct "
716 << "Bp"
717 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700718 << " : public ::android::hardware::BpInterface<IHw"
719 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700720 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700721
722 out.indent();
723
724 out << "explicit Bp"
725 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700726 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700727 << "\n\n";
728
Yifan Hong10fe0b52016-10-19 14:20:17 -0700729 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700730
Yifan Hong068c5522016-10-31 14:07:25 -0700731 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
732 method->generateCppSignature(out);
733 out << " override;\n";
734 return OK;
735 });
Steven Moreland9c387612016-09-07 09:54:26 -0700736
737 if (err != OK) {
738 return err;
739 }
Andreas Huber881227d2016-08-02 14:20:21 -0700740
741 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700742 out << "};\n\n";
743
744 enterLeaveNamespace(out, false /* enter */);
745
746 out << "\n#endif // " << guard << "\n";
747
748 return OK;
749}
750
Andreas Huberb82318c2016-08-02 14:45:54 -0700751status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700752
Andreas Huberb82318c2016-08-02 14:45:54 -0700753 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700754 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700755 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700756
757 std::string ifaceName;
758 std::string baseName;
759
Yifan Hongfe95aa22016-10-19 17:26:45 -0700760 const Interface *iface = nullptr;
761 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700762 if (!AST::isInterface(&ifaceName)) {
763 baseName = "types";
764 isInterface = false;
765 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700766 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700767 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700768 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700769 }
770
771 path.append(baseName);
772
773 if (baseName != "types") {
774 path.append("All");
775 }
776
777 path.append(".cpp");
778
Andreas Huberd2943e12016-08-05 11:59:31 -0700779 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700780 FILE *file = fopen(path.c_str(), "w");
781
782 if (file == NULL) {
783 return -errno;
784 }
785
786 Formatter out(file);
787
Martijn Coenen7b295242016-11-04 16:52:56 +0100788
789 out << "#include <cutils/trace.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700790 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700791 // This is a no-op for IServiceManager itself.
792 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
793
Steven Morelandee88eed2016-10-31 17:49:00 -0700794 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
795 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
796 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700797
798 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700799 generateCppPackageInclude(out,
800 superType->fqName(),
801 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700802 }
Andreas Huber881227d2016-08-02 14:20:21 -0700803 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700804 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800805 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700806 }
807
808 out << "\n";
809
810 enterLeaveNamespace(out, true /* enter */);
811 out << "\n";
812
813 status_t err = generateTypeSource(out, ifaceName);
814
815 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700816 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700817 out << "constexpr ::android::hardware::hidl_version "
818 << ifaceName
819 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700820
821 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800822 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700823 << iface->getBaseName()
824 << "::descriptor(\""
825 << iface->fqName().string()
826 << "\");\n\n";
827
Yifan Hong158655a2016-11-08 12:34:07 -0800828 out << "int I"
829 << iface->getBaseName()
830 << "::hidlStaticBlock = []() -> int {\n";
831 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800832 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800833 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800834 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800835 out.indentBlock(2, [&] {
836 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
837 out.indentBlock([&] {
838 out << "return new Bn"
839 << iface->getBaseName()
840 << "(reinterpret_cast<I"
841 << iface->getBaseName()
842 << " *>(iIntf));\n";
843 });
844 out << "};\n";
845 });
846 out << "return 1;\n";
847 });
848 out << "}();\n\n";
849
Yifan Hongfe95aa22016-10-19 17:26:45 -0700850 err = generateInterfaceSource(out);
851 }
852
853 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700854 err = generateProxySource(out, baseName);
855 }
856
857 if (err == OK && isInterface) {
858 err = generateStubSource(out, baseName);
859 }
860
Steven Moreland40786312016-08-16 10:29:40 -0700861 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700862 err = generatePassthroughSource(out);
863 }
864
865 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700866 const Interface *iface = mRootScope->getInterface();
867
Steven Moreland0693f312016-11-09 15:06:14 -0800868 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
Steven Moreland9c387612016-09-07 09:54:26 -0700869 << baseName << ", "
870 << "\"" << iface->fqName().package()
Steven Moreland7e367bf2016-11-04 11:31:41 -0700871 << iface->fqName().atVersion()
872 << "\")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700873 }
874
Andreas Huber881227d2016-08-02 14:20:21 -0700875 enterLeaveNamespace(out, false /* enter */);
876
877 return err;
878}
879
Steven Moreland67f67b42016-09-29 08:59:02 -0700880// static
881void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
882 out << "if (" << nonNull << " == nullptr) {\n";
883 out.indent();
884 out << "return ::android::hardware::Status::fromExceptionCode(\n";
885 out.indent();
886 out.indent();
887 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
888 out.unindent();
889 out.unindent();
890 out.unindent();
891 out << "}\n\n";
892}
893
Andreas Huber881227d2016-08-02 14:20:21 -0700894status_t AST::generateTypeSource(
895 Formatter &out, const std::string &ifaceName) const {
896 return mRootScope->emitTypeDefinitions(out, ifaceName);
897}
898
Andreas Hubere7ff2282016-08-16 13:50:03 -0700899void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700900 Formatter &out,
901 const std::vector<TypedVar *> &args,
902 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700903 if (args.empty()) {
904 return;
905 }
906
907 for (const auto &arg : args) {
908 const Type &type = arg->type();
909
Yifan Hong3b320f82016-11-01 15:15:54 -0700910 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700911 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700912 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700913 << ";\n";
914 }
915
916 out << "\n";
917}
918
Andreas Huber881227d2016-08-02 14:20:21 -0700919void AST::emitCppReaderWriter(
920 Formatter &out,
921 const std::string &parcelObj,
922 bool parcelObjIsPointer,
923 const TypedVar *arg,
924 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700925 Type::ErrorMode mode,
926 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700927 const Type &type = arg->type();
928
Andreas Huber881227d2016-08-02 14:20:21 -0700929 type.emitReaderWriter(
930 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700931 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700932 parcelObj,
933 parcelObjIsPointer,
934 isReader,
935 mode);
936}
937
Yifan Hongbf459bc2016-08-23 16:50:37 -0700938void AST::emitCppResolveReferences(
939 Formatter &out,
940 const std::string &parcelObj,
941 bool parcelObjIsPointer,
942 const TypedVar *arg,
943 bool isReader,
944 Type::ErrorMode mode,
945 bool addPrefixToName) const {
946 const Type &type = arg->type();
947 if(type.needsResolveReferences()) {
948 type.emitResolveReferences(
949 out,
950 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
951 isReader, // nameIsPointer
952 parcelObj,
953 parcelObjIsPointer,
954 isReader,
955 mode);
956 }
957}
958
Yifan Hong068c5522016-10-31 14:07:25 -0700959status_t AST::generateProxyMethodSource(Formatter &out,
960 const std::string &klassName,
961 const Method *method,
962 const Interface *superInterface) const {
963
964 method->generateCppSignature(out,
965 klassName,
966 true /* specify namespaces */);
967
968 const bool returnsValue = !method->results().empty();
969 const TypedVar *elidedReturn = method->canElideCallback();
970
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800971 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700972
973 out.indent();
974
975 if (returnsValue && elidedReturn == nullptr) {
976 generateCheckNonNull(out, "_hidl_cb");
977 }
978
979 status_t status = generateCppInstrumentationCall(
980 out,
981 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700982 method);
983 if (status != OK) {
984 return status;
985 }
986
987 out << "::android::hardware::Parcel _hidl_data;\n";
988 out << "::android::hardware::Parcel _hidl_reply;\n";
989 out << "::android::status_t _hidl_err;\n";
990 out << "::android::hardware::Status _hidl_status;\n\n";
991
992 declareCppReaderLocals(
993 out, method->results(), true /* forResults */);
994
995 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandd39133b2016-11-11 12:30:08 -0800996 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800997 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -0800998 } else {
999 out << superInterface->fqName().cppNamespace()
1000 << "::I"
1001 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001002 }
1003 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001004 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1005
1006 // First DFS: write all buffers and resolve pointers for parent
1007 for (const auto &arg : method->args()) {
1008 emitCppReaderWriter(
1009 out,
1010 "_hidl_data",
1011 false /* parcelObjIsPointer */,
1012 arg,
1013 false /* reader */,
1014 Type::ErrorMode_Goto,
1015 false /* addPrefixToName */);
1016 }
1017
1018 // Second DFS: resolve references.
1019 for (const auto &arg : method->args()) {
1020 emitCppResolveReferences(
1021 out,
1022 "_hidl_data",
1023 false /* parcelObjIsPointer */,
1024 arg,
1025 false /* reader */,
1026 Type::ErrorMode_Goto,
1027 false /* addPrefixToName */);
1028 }
1029
1030 out << "_hidl_err = remote()->transact("
1031 << method->getSerialId()
1032 << " /* "
1033 << method->name()
1034 << " */, _hidl_data, &_hidl_reply";
1035
1036 if (method->isOneway()) {
1037 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1038 }
1039 out << ");\n";
1040
1041 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1042
1043 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001044 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001045 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1046 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1047
1048
1049 // First DFS: write all buffers and resolve pointers for parent
1050 for (const auto &arg : method->results()) {
1051 emitCppReaderWriter(
1052 out,
1053 "_hidl_reply",
1054 false /* parcelObjIsPointer */,
1055 arg,
1056 true /* reader */,
1057 Type::ErrorMode_Goto,
1058 true /* addPrefixToName */);
1059 }
1060
1061 // Second DFS: resolve references.
1062 for (const auto &arg : method->results()) {
1063 emitCppResolveReferences(
1064 out,
1065 "_hidl_reply",
1066 false /* parcelObjIsPointer */,
1067 arg,
1068 true /* reader */,
1069 Type::ErrorMode_Goto,
1070 true /* addPrefixToName */);
1071 }
1072
1073 if (returnsValue && elidedReturn == nullptr) {
1074 out << "_hidl_cb(";
1075
1076 bool first = true;
1077 for (const auto &arg : method->results()) {
1078 if (!first) {
1079 out << ", ";
1080 }
1081
1082 if (arg->type().resultNeedsDeref()) {
1083 out << "*";
1084 }
1085 out << "_hidl_out_" << arg->name();
1086
1087 first = false;
1088 }
1089
1090 out << ");\n\n";
1091 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001092 }
1093 status = generateCppInstrumentationCall(
1094 out,
1095 InstrumentationEvent::CLIENT_API_EXIT,
1096 method);
1097 if (status != OK) {
1098 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001099 }
1100
1101 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001102 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1103 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001104 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001105 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1106 } else {
1107 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1108 out << "return ::android::hardware::Return<void>();\n\n";
1109 }
1110
1111 out.unindent();
1112 out << "_hidl_error:\n";
1113 out.indent();
1114 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1115 out << "return ::android::hardware::Return<";
1116 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001117 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001118 } else {
1119 out << "void";
1120 }
1121 out << ">(_hidl_status);\n";
1122
1123 out.unindent();
1124 out << "}\n\n";
1125 return OK;
1126}
1127
Andreas Huber881227d2016-08-02 14:20:21 -07001128status_t AST::generateProxySource(
1129 Formatter &out, const std::string &baseName) const {
1130 const std::string klassName = "Bp" + baseName;
1131
1132 out << klassName
1133 << "::"
1134 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001135 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001136
1137 out.indent();
1138 out.indent();
1139
1140 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001141 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001142 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001143 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001144 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001145 << mPackage.string()
1146 << "::I"
1147 << baseName
1148 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001149
Andreas Huber881227d2016-08-02 14:20:21 -07001150 out.unindent();
1151 out.unindent();
1152 out << "}\n\n";
1153
Yifan Hong068c5522016-10-31 14:07:25 -07001154 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1155 return generateProxyMethodSource(out, klassName, method, superInterface);
1156 });
Andreas Huber881227d2016-08-02 14:20:21 -07001157
Yifan Hong068c5522016-10-31 14:07:25 -07001158 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001159}
1160
1161status_t AST::generateStubSource(
1162 Formatter &out, const std::string &baseName) const {
1163 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1164 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001165 << ", "
1166 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001167 << "::I"
1168 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001169 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001170
1171 const std::string klassName = "Bn" + baseName;
1172
Steven Moreland40786312016-08-16 10:29:40 -07001173 out << klassName
1174 << "::"
1175 << klassName
1176 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1177
1178 out.indent();
1179 out.indent();
1180
1181 out << ": BnInterface"
1182 << "<I"
1183 << baseName
1184 << ", IHw"
1185 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001186 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001187 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001188 << mPackage.string()
1189 << "::I"
1190 << baseName
1191 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001192
1193 out.unindent();
1194 out.unindent();
1195 out << "}\n\n";
1196
Andreas Huber881227d2016-08-02 14:20:21 -07001197 out << "::android::status_t " << klassName << "::onTransact(\n";
1198
1199 out.indent();
1200 out.indent();
1201
Iliyan Malchev549e2592016-08-10 08:59:12 -07001202 out << "uint32_t _hidl_code,\n"
1203 << "const ::android::hardware::Parcel &_hidl_data,\n"
1204 << "::android::hardware::Parcel *_hidl_reply,\n"
1205 << "uint32_t _hidl_flags,\n"
1206 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001207
1208 out.unindent();
1209
Iliyan Malchev549e2592016-08-10 08:59:12 -07001210 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001211 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001212 out.indent();
1213
1214 const Interface *iface = mRootScope->getInterface();
1215
Yifan Hong10fe0b52016-10-19 14:20:17 -07001216 for (const auto &tuple : iface->allMethodsFromRoot()) {
1217 const Method *method = tuple.method();
1218 const Interface *superInterface = tuple.interface();
1219 out << "case "
1220 << method->getSerialId()
1221 << " /* "
1222 << method->name()
1223 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001224
Yifan Hong10fe0b52016-10-19 14:20:17 -07001225 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001226
Yifan Hong10fe0b52016-10-19 14:20:17 -07001227 status_t err =
1228 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001229
Yifan Hong10fe0b52016-10-19 14:20:17 -07001230 if (err != OK) {
1231 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001232 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001233
1234 out.unindent();
1235 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001236 }
1237
1238 out << "default:\n{\n";
1239 out.indent();
1240
Andreas Huber8a82ff72016-08-04 10:29:39 -07001241 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001242 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001243 << ">::onTransact(\n";
1244
1245 out.indent();
1246 out.indent();
1247
Iliyan Malchev549e2592016-08-10 08:59:12 -07001248 out << "_hidl_code, _hidl_data, _hidl_reply, "
1249 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001250
1251 out.unindent();
1252 out.unindent();
1253
1254 out.unindent();
1255 out << "}\n";
1256
1257 out.unindent();
1258 out << "}\n\n";
1259
Iliyan Malchev549e2592016-08-10 08:59:12 -07001260 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001261 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001262 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001263 out.indent();
1264 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001265 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1266 out << "_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001267 out.unindent();
1268 out.unindent();
1269
1270 out.unindent();
1271 out << "}\n\n";
1272
Iliyan Malchev549e2592016-08-10 08:59:12 -07001273 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001274
1275 out.unindent();
1276 out << "}\n\n";
1277
1278 return OK;
1279}
1280
1281status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001282 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001283 out << "if (!_hidl_data.enforceInterface(";
1284
Steven Morelandd39133b2016-11-11 12:30:08 -08001285 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -08001286 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -08001287 } else {
1288 out << iface->fqName().cppNamespace()
1289 << "::I"
1290 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001291 }
1292
1293 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001294
Andreas Huber881227d2016-08-02 14:20:21 -07001295 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001296 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001297 out << "break;\n";
1298 out.unindent();
1299 out << "}\n\n";
1300
Andreas Huber5e44a292016-09-27 14:52:39 -07001301 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001302
Yifan Hongbf459bc2016-08-23 16:50:37 -07001303 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001304 for (const auto &arg : method->args()) {
1305 emitCppReaderWriter(
1306 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001307 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001308 false /* parcelObjIsPointer */,
1309 arg,
1310 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001311 Type::ErrorMode_Break,
1312 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001313 }
1314
Yifan Hongbf459bc2016-08-23 16:50:37 -07001315 // Second DFS: resolve references
1316 for (const auto &arg : method->args()) {
1317 emitCppResolveReferences(
1318 out,
1319 "_hidl_data",
1320 false /* parcelObjIsPointer */,
1321 arg,
1322 true /* reader */,
1323 Type::ErrorMode_Break,
1324 false /* addPrefixToName */);
1325 }
1326
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001327 status_t status = generateCppInstrumentationCall(
1328 out,
1329 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001330 method);
1331 if (status != OK) {
1332 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001333 }
1334
Andreas Huber881227d2016-08-02 14:20:21 -07001335 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001336 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001337
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001338 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001339 out << elidedReturn->type().getCppResultType()
1340 << " "
1341 << elidedReturn->name()
1342 << " = "
1343 << method->name()
1344 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001345
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001346 bool first = true;
1347 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001348 if (!first) {
1349 out << ", ";
1350 }
1351
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001352 if (arg->type().resultNeedsDeref()) {
1353 out << "*";
1354 }
1355
1356 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001357
1358 first = false;
1359 }
1360
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001361 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001362 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1363 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001364
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001365 elidedReturn->type().emitReaderWriter(
1366 out,
1367 elidedReturn->name(),
1368 "_hidl_reply",
1369 true, /* parcelObjIsPointer */
1370 false, /* isReader */
1371 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001372
Yifan Hongbf459bc2016-08-23 16:50:37 -07001373 emitCppResolveReferences(
1374 out,
1375 "_hidl_reply",
1376 true /* parcelObjIsPointer */,
1377 elidedReturn,
1378 false /* reader */,
1379 Type::ErrorMode_Ignore,
1380 false /* addPrefixToName */);
1381
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001382 status_t status = generateCppInstrumentationCall(
1383 out,
1384 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001385 method);
1386 if (status != OK) {
1387 return status;
1388 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001389
Iliyan Malchev549e2592016-08-10 08:59:12 -07001390 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001391 } else {
1392 if (returnsValue) {
1393 out << "bool _hidl_callbackCalled = false;\n\n";
1394 }
Andreas Huber881227d2016-08-02 14:20:21 -07001395
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001396 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001397
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001398 bool first = true;
1399 for (const auto &arg : method->args()) {
1400 if (!first) {
1401 out << ", ";
1402 }
Andreas Huber881227d2016-08-02 14:20:21 -07001403
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001404 if (arg->type().resultNeedsDeref()) {
1405 out << "*";
1406 }
1407
1408 out << arg->name();
1409
1410 first = false;
1411 }
1412
1413 if (returnsValue) {
1414 if (!first) {
1415 out << ", ";
1416 }
1417
1418 out << "[&](";
1419
1420 first = true;
1421 for (const auto &arg : method->results()) {
1422 if (!first) {
1423 out << ", ";
1424 }
1425
1426 out << "const auto &" << arg->name();
1427
1428 first = false;
1429 }
1430
1431 out << ") {\n";
1432 out.indent();
1433 out << "_hidl_callbackCalled = true;\n\n";
1434
Yifan Hong859e53f2016-11-14 19:08:24 -08001435 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1436 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001437
Yifan Hongbf459bc2016-08-23 16:50:37 -07001438 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001439 for (const auto &arg : method->results()) {
1440 emitCppReaderWriter(
1441 out,
1442 "_hidl_reply",
1443 true /* parcelObjIsPointer */,
1444 arg,
1445 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001446 Type::ErrorMode_Ignore,
1447 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001448 }
1449
Yifan Hongbf459bc2016-08-23 16:50:37 -07001450 // Second DFS: resolve references
1451 for (const auto &arg : method->results()) {
1452 emitCppResolveReferences(
1453 out,
1454 "_hidl_reply",
1455 true /* parcelObjIsPointer */,
1456 arg,
1457 false /* reader */,
1458 Type::ErrorMode_Ignore,
1459 false /* addPrefixToName */);
1460 }
1461
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001462 status_t status = generateCppInstrumentationCall(
1463 out,
1464 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001465 method);
1466 if (status != OK) {
1467 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001468 }
1469
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001470 out << "_hidl_cb(*_hidl_reply);\n";
1471
1472 out.unindent();
1473 out << "}\n";
1474 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001475 out << ");\n\n";
1476
1477 // What to do if the stub implementation has a synchronous callback
1478 // which does not get invoked? This is not a transport error but a
1479 // service error of sorts. For now, return OK to the caller, as this is
1480 // not a transport error.
1481 //
1482 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001483
1484 if (returnsValue) {
1485 out << "if (!_hidl_callbackCalled) {\n";
1486 out.indent();
1487 }
1488
Yifan Hong859e53f2016-11-14 19:08:24 -08001489 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1490 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001491
1492 if (returnsValue) {
1493 out.unindent();
1494 out << "}\n\n";
1495 }
Andreas Huber881227d2016-08-02 14:20:21 -07001496 }
1497
1498 out << "break;\n";
1499
1500 return OK;
1501}
1502
Steven Moreland69e7c702016-09-09 11:16:32 -07001503status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1504 std::string ifaceName;
1505 if (!AST::isInterface(&ifaceName)) {
1506 // types.hal does not get a stub header.
1507 return OK;
1508 }
1509
1510 const Interface *iface = mRootScope->getInterface();
1511
1512 const std::string baseName = iface->getBaseName();
1513 const std::string klassName = "Bs" + baseName;
1514
1515 bool supportOneway = iface->hasOnewayMethods();
1516
1517 std::string path = outputPath;
1518 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1519 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1520 path.append(klassName);
1521 path.append(".h");
1522
1523 CHECK(Coordinator::MakeParentHierarchy(path));
1524 FILE *file = fopen(path.c_str(), "w");
1525
1526 if (file == NULL) {
1527 return -errno;
1528 }
1529
1530 Formatter out(file);
1531
1532 const std::string guard = makeHeaderGuard(klassName);
1533
1534 out << "#ifndef " << guard << "\n";
1535 out << "#define " << guard << "\n\n";
1536
1537 std::vector<std::string> packageComponents;
1538 getPackageAndVersionComponents(
1539 &packageComponents, false /* cpp_compatible */);
1540
1541 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001542
1543 generateCppPackageInclude(out, mPackage, ifaceName);
1544 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001545
1546 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001547 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001548 }
1549
1550 enterLeaveNamespace(out, true /* enter */);
1551 out << "\n";
1552
1553 out << "struct "
1554 << klassName
1555 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001556 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001557
1558 out.indent();
1559 out << "explicit "
1560 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001561 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001562 << ifaceName
1563 << "> impl);\n";
1564
Yifan Hong068c5522016-10-31 14:07:25 -07001565 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1566 return generatePassthroughMethod(out, method);
1567 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001568
1569 if (err != OK) {
1570 return err;
1571 }
1572
1573 out.unindent();
1574 out << "private:\n";
1575 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001576 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001577
1578 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001579 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001580
1581 out << "\n";
1582
1583 out << "::android::hardware::Return<void> addOnewayTask("
1584 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001585 }
1586
1587 out.unindent();
1588
1589 out << "};\n\n";
1590
1591 enterLeaveNamespace(out, false /* enter */);
1592
1593 out << "\n#endif // " << guard << "\n";
1594
1595 return OK;
1596}
1597
Yifan Hongfe95aa22016-10-19 17:26:45 -07001598status_t AST::generateInterfaceSource(Formatter &out) const {
1599 const Interface *iface = mRootScope->getInterface();
1600
Yifan Hong2d7126b2016-10-20 15:12:57 -07001601 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001602 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001603 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001604
1605 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001606 out << "// static \n"
1607 << childTypeResult
1608 << " I"
1609 << iface->getBaseName()
1610 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001611 << superType->getCppArgumentType()
1612 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001613 out.indent();
1614 out << "return ::android::hardware::castInterface<";
1615 out << "I" << iface->getBaseName() << ", "
1616 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001617 << "Bp" << iface->getBaseName() << ", "
1618 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001619 << ">(\n";
1620 out.indent();
1621 out.indent();
1622 out << "parent, \""
1623 << iface->fqName().string()
1624 << "\");\n";
1625 out.unindent();
1626 out.unindent();
1627 out.unindent();
1628 out << "}\n\n";
1629 }
1630 }
1631
1632 return OK;
1633}
1634
Steven Moreland69e7c702016-09-09 11:16:32 -07001635status_t AST::generatePassthroughSource(Formatter &out) const {
1636 const Interface *iface = mRootScope->getInterface();
1637
1638 const std::string baseName = iface->getBaseName();
1639 const std::string klassName = "Bs" + baseName;
1640
1641 out << klassName
1642 << "::"
1643 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001644 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001645 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001646 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001647 << iface->fqName().string()
1648 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001649 if (iface->hasOnewayMethods()) {
1650 out << "\n";
1651 out.indentBlock([&] {
1652 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1653 });
1654 }
1655 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001656
1657 if (iface->hasOnewayMethods()) {
1658 out << "::android::hardware::Return<void> "
1659 << klassName
1660 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1661 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001662 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001663 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001664 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1665 out.indent();
1666 out.indent();
1667 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1668 out.unindent();
1669 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001670 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001671 out << "}\n";
1672
Steven Morelandd366c262016-10-11 15:29:10 -07001673 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001674
1675 out.unindent();
1676 out << "}\n\n";
1677
1678
1679 }
1680
1681 return OK;
1682}
1683
Martijn Coenen7b295242016-11-04 16:52:56 +01001684status_t AST::generateCppAtraceCall(Formatter &out,
1685 InstrumentationEvent event,
1686 const Method *method) const {
1687 const Interface *iface = mRootScope->getInterface();
1688 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1689 switch (event) {
1690 case SERVER_API_ENTRY:
1691 {
1692 out << "atrace_begin(ATRACE_TAG_HAL, \""
1693 << baseString + "::server\");\n";
1694 break;
1695 }
1696 case CLIENT_API_ENTRY:
1697 {
1698 out << "atrace_begin(ATRACE_TAG_HAL, \""
1699 << baseString + "::client\");\n";
1700 break;
1701 }
1702 case PASSTHROUGH_ENTRY:
1703 {
1704 out << "atrace_begin(ATRACE_TAG_HAL, \""
1705 << baseString + "::passthrough\");\n";
1706 break;
1707 }
1708 case SERVER_API_EXIT:
1709 case CLIENT_API_EXIT:
1710 case PASSTHROUGH_EXIT:
1711 {
1712 out << "atrace_end(ATRACE_TAG_HAL);\n";
1713 break;
1714 }
1715 default:
1716 {
1717 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1718 return UNKNOWN_ERROR;
1719 }
1720 }
1721
1722 return OK;
1723}
1724
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001725status_t AST::generateCppInstrumentationCall(
1726 Formatter &out,
1727 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001728 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001729 status_t err = generateCppAtraceCall(out, event, method);
1730 if (err != OK) {
1731 return err;
1732 }
1733
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001734 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1735 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001736 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001737 std::string event_str = "";
1738 switch (event) {
1739 case SERVER_API_ENTRY:
1740 {
1741 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1742 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001743 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001744 << (arg->type().resultNeedsDeref() ? "" : "&")
1745 << arg->name()
1746 << ");\n";
1747 }
1748 break;
1749 }
1750 case SERVER_API_EXIT:
1751 {
1752 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001753 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001754 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001755 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001756 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001757 }
1758 break;
1759 }
1760 case CLIENT_API_ENTRY:
1761 {
1762 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1763 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001764 out << "_hidl_args.push_back((void *)&"
1765 << arg->name()
1766 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001767 }
1768 break;
1769 }
1770 case CLIENT_API_EXIT:
1771 {
1772 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1773 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001774 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001775 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001776 << "_hidl_out_"
1777 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001778 << ");\n";
1779 }
1780 break;
1781 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001782 case PASSTHROUGH_ENTRY:
1783 {
1784 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1785 for (const auto &arg : method->args()) {
1786 out << "_hidl_args.push_back((void *)&"
1787 << arg->name()
1788 << ");\n";
1789 }
1790 break;
1791 }
1792 case PASSTHROUGH_EXIT:
1793 {
1794 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001795 for (const auto &arg : method->results()) {
1796 out << "_hidl_args.push_back((void *)&"
1797 << arg->name()
1798 << ");\n";
1799 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001800 break;
1801 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001802 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001803 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001804 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001805 return UNKNOWN_ERROR;
1806 }
1807 }
1808
Steven Moreland031ccf12016-10-31 15:54:38 -07001809 const Interface *iface = mRootScope->getInterface();
1810
Steven Moreland1ab31442016-11-03 18:37:51 -07001811 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001812 out.indent();
1813 out << "callback("
1814 << event_str
1815 << ", \""
1816 << mPackage.package()
1817 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001818 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001819 << "\", \""
1820 << iface->localName()
1821 << "\", \""
1822 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001823 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001824 out.unindent();
1825 out << "}\n";
1826 out.unindent();
1827 out << "}\n\n";
1828
1829 return OK;
1830}
1831
Andreas Huber881227d2016-08-02 14:20:21 -07001832} // namespace android
1833