1 /*
2 * Copyright (C) 2018, 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
17 #include "generate_ndk.h"
18
19 #include "aidl.h"
20 #include "aidl_language.h"
21 #include "aidl_to_cpp_common.h"
22 #include "aidl_to_ndk.h"
23 #include "logging.h"
24
25 #include <android-base/stringprintf.h>
26
27 namespace android {
28 namespace aidl {
29 namespace ndk {
30
31 static constexpr const char* kDescriptor = "descriptor";
32 static constexpr const char* kVersion = "version";
33 static constexpr const char* kHash = "hash";
34 static constexpr const char* kCachedVersion = "_aidl_cached_version";
35 static constexpr const char* kCachedHash = "_aidl_cached_hash";
36 static constexpr const char* kCachedHashMutex = "_aidl_cached_hash_mutex";
37
38 namespace internals {
39 // 4 outputs for NDK for each type: Header, BpHeader, BnHeader, Source
40 void GenerateHeader(CodeWriter& out, const AidlTypenames& types,
41 const AidlDefinedType& defined_type, const Options& options);
42 void GenerateClientHeader(CodeWriter& out, const AidlTypenames& types,
43 const AidlDefinedType& defined_type, const Options& options);
44 void GenerateServerHeader(CodeWriter& out, const AidlTypenames& types,
45 const AidlDefinedType& defined_type, const Options& options);
46 void GenerateSource(CodeWriter& out, const AidlTypenames& types,
47 const AidlDefinedType& defined_type, const Options& options);
48
49 // Header contains ClassDecl of a root type
50 void GenerateInterfaceClassDecl(CodeWriter& out, const AidlTypenames& types,
51 const AidlInterface& iface, const Options& options);
52 void GenerateParcelClassDecl(CodeWriter& out, const AidlTypenames& types,
53 const AidlStructuredParcelable& parcelable, const Options& options);
54 void GenerateParcelClassDecl(CodeWriter& out, const AidlTypenames& types,
55 const AidlUnionDecl& union_decl, const Options& options);
56 void GenerateEnumClassDecl(CodeWriter& out, const AidlTypenames& types,
57 const AidlEnumDeclaration& enum_decl, const Options& options);
58
59 // BpHeader/BnHeader for interface
60 void GenerateClientHeader(CodeWriter& out, const AidlTypenames& types,
61 const AidlInterface& defined_type, const Options& options);
62 void GenerateServerHeader(CodeWriter& out, const AidlTypenames& types,
63 const AidlInterface& defined_type, const Options& options);
64
65 // Source for interface
66 void GenerateSource(CodeWriter& out, const AidlTypenames& types, const AidlInterface& iface,
67 const Options& options);
68 void GenerateClassSource(CodeWriter& out, const AidlTypenames& types,
69 const AidlInterface& defined_type, const Options& options);
70 void GenerateClientSource(CodeWriter& out, const AidlTypenames& types,
71 const AidlInterface& defined_type, const Options& options);
72 void GenerateServerSource(CodeWriter& out, const AidlTypenames& types,
73 const AidlInterface& defined_type, const Options& options);
74 void GenerateInterfaceSource(CodeWriter& out, const AidlTypenames& types,
75 const AidlInterface& defined_type, const Options& options);
76
77 // Source for structured parcelable
78 void GenerateParcelSource(CodeWriter& out, const AidlTypenames& types,
79 const AidlStructuredParcelable& defined_type, const Options& options);
80
81 // Source for union
82 void GenerateParcelSource(CodeWriter& out, const AidlTypenames& types,
83 const AidlUnionDecl& defined_type, const Options& options);
84
85 // Compare headers so that <android/..> and <aidl/..> comes after other (probably) std headers.
86 struct HeaderComp {
rankandroid::aidl::ndk::internals::HeaderComp87 static int rank(const string& a) {
88 return base::StartsWith(a, "aidl/") ? 2 : base::StartsWith(a, "android/") ? 1 : 0;
89 }
operator ()android::aidl::ndk::internals::HeaderComp90 bool operator()(const string& a, const string& b) const {
91 return std::make_tuple(rank(a), a) < std::make_tuple(rank(b), b);
92 }
93 };
94 } // namespace internals
95
96 using namespace internals;
97 using cpp::ClassNames;
98 using cpp::GetQualifiedName;
99
GenerateNdk(const string & output_file,const Options & options,const AidlTypenames & types,const AidlDefinedType & defined_type,const IoDelegate & io_delegate)100 void GenerateNdk(const string& output_file, const Options& options, const AidlTypenames& types,
101 const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
102 using GenFn = void (*)(CodeWriter & out, const AidlTypenames& types,
103 const AidlDefinedType& defined_type, const Options& options);
104 // Wrap Generate* function to handle CodeWriter for a file.
105 auto gen = [&](auto file, GenFn fn) {
106 unique_ptr<CodeWriter> writer(io_delegate.GetCodeWriter(file));
107 fn(*writer, types, defined_type, options);
108 AIDL_FATAL_IF(!writer->Close(), defined_type) << "I/O Error!";
109 };
110
111 gen(options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::RAW), &GenerateHeader);
112 gen(options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::CLIENT),
113 &GenerateClientHeader);
114 gen(options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::SERVER),
115 &GenerateServerHeader);
116 gen(output_file, &GenerateSource);
117 }
118
119 namespace internals {
120
EnterNdkNamespace(CodeWriter & out,const AidlDefinedType & defined_type)121 void EnterNdkNamespace(CodeWriter& out, const AidlDefinedType& defined_type) {
122 out << "namespace aidl {\n";
123 cpp::EnterNamespace(out, defined_type);
124 }
LeaveNdkNamespace(CodeWriter & out,const AidlDefinedType & defined_type)125 void LeaveNdkNamespace(CodeWriter& out, const AidlDefinedType& defined_type) {
126 cpp::LeaveNamespace(out, defined_type);
127 out << "} // namespace aidl\n";
128 }
129
StatusCheckGoto(CodeWriter & out)130 static void StatusCheckGoto(CodeWriter& out) {
131 out << "if (_aidl_ret_status != STATUS_OK) goto _aidl_error;\n\n";
132 }
StatusCheckBreak(CodeWriter & out)133 static void StatusCheckBreak(CodeWriter& out) {
134 out << "if (_aidl_ret_status != STATUS_OK) break;\n\n";
135 }
StatusCheckReturn(CodeWriter & out)136 static void StatusCheckReturn(CodeWriter& out) {
137 out << "if (_aidl_ret_status != STATUS_OK) return _aidl_ret_status;\n\n";
138 }
139
140 void GenerateHeaderIncludes(CodeWriter& out, const AidlTypenames& types,
141 const AidlDefinedType& defined_type, const Options& options);
142
143 void GenerateClassDecl(CodeWriter& out, const AidlTypenames& types,
144 const AidlDefinedType& defined_type, const Options& options);
145
GenerateNestedTypeDecls(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)146 void GenerateNestedTypeDecls(CodeWriter& out, const AidlTypenames& types,
147 const AidlDefinedType& defined_type, const Options& options) {
148 auto visit = [&](const auto& nested) { GenerateClassDecl(out, types, nested, options); };
149 AIDL_FATAL_IF(!TopologicalVisit(defined_type.GetNestedTypes(), visit), defined_type)
150 << "Cycle detected.";
151 }
152
GenerateHeaderDefinitions(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)153 void GenerateHeaderDefinitions(CodeWriter& out, const AidlTypenames& types,
154 const AidlDefinedType& defined_type, const Options& options) {
155 struct Visitor : AidlVisitor {
156 CodeWriter& out;
157 const AidlTypenames& types;
158 const Options& options;
159 Visitor(CodeWriter& out, const AidlTypenames& types, const Options& options)
160 : out(out), types(types), options(options) {}
161
162 void Visit(const AidlEnumDeclaration& enum_decl) override {
163 const auto backing_type = NdkNameOf(types, enum_decl.GetBackingType(), StorageMode::STACK);
164 EnterNdkNamespace(out, enum_decl);
165 out << cpp::GenerateEnumToString(enum_decl, backing_type);
166 LeaveNdkNamespace(out, enum_decl);
167
168 out << "namespace ndk {\n";
169 out << "namespace internal {\n";
170 out << cpp::GenerateEnumValues(enum_decl, {"aidl"});
171 out << "} // namespace internal\n";
172 out << "} // namespace ndk\n";
173 }
174
175 void Visit(const AidlStructuredParcelable& parcelable) override {
176 if (parcelable.IsGeneric()) {
177 GenerateParcelSource(out, types, parcelable, options);
178 }
179 }
180
181 void Visit(const AidlUnionDecl& union_decl) override {
182 if (union_decl.IsGeneric()) {
183 GenerateParcelSource(out, types, union_decl, options);
184 }
185 }
186
187 } v(out, types, options);
188 VisitTopDown(v, defined_type);
189 }
190
GenerateHeader(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)191 void GenerateHeader(CodeWriter& out, const AidlTypenames& types,
192 const AidlDefinedType& defined_type, const Options& options) {
193 out << "#pragma once\n\n";
194 GenerateHeaderIncludes(out, types, defined_type, options);
195 cpp::GenerateForwardDecls(out, defined_type, true);
196 EnterNdkNamespace(out, defined_type);
197 GenerateClassDecl(out, types, defined_type, options);
198 LeaveNdkNamespace(out, defined_type);
199 GenerateHeaderDefinitions(out, types, defined_type, options);
200 }
201
GenerateClientHeader(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)202 void GenerateClientHeader(CodeWriter& out, const AidlTypenames& types,
203 const AidlDefinedType& defined_type, const Options& options) {
204 if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
205 GenerateClientHeader(out, types, *iface, options);
206 } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
207 out << "#error TODO(b/111362593) defined_types do not have bp classes\n";
208 } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
209 out << "#error TODO(b/111362593) defined_types do not have bp classes\n";
210 } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
211 out << "#error TODO(b/111362593) enums do not have bp classes\n";
212 } else {
213 AIDL_FATAL(defined_type) << "Unrecognized type sent for NDK generation.";
214 }
215 }
216
GenerateServerHeader(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)217 void GenerateServerHeader(CodeWriter& out, const AidlTypenames& types,
218 const AidlDefinedType& defined_type, const Options& options) {
219 if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
220 GenerateServerHeader(out, types, *iface, options);
221 } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
222 out << "#error TODO(b/111362593) defined_types do not have bn classes\n";
223 } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
224 out << "#error TODO(b/111362593) defined_types do not have bn classes\n";
225 } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
226 out << "#error TODO(b/111362593) enums do not have bn classes\n";
227 } else {
228 AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
229 }
230 }
231
GenerateSource(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)232 void GenerateSource(CodeWriter& out, const AidlTypenames& types,
233 const AidlDefinedType& defined_type, const Options& options) {
234 struct Visitor : AidlVisitor {
235 CodeWriter& out;
236 const AidlTypenames& types;
237 const Options& options;
238 Visitor(CodeWriter& out, const AidlTypenames& types, const Options& options)
239 : out(out), types(types), options(options) {}
240
241 void Visit(const AidlInterface& interface) override {
242 GenerateSource(out, types, interface, options);
243 }
244
245 void Visit(const AidlStructuredParcelable& parcelable) override {
246 if (!parcelable.IsGeneric()) {
247 GenerateParcelSource(out, types, parcelable, options);
248 }
249 }
250
251 void Visit(const AidlUnionDecl& union_decl) override {
252 if (!union_decl.IsGeneric()) {
253 GenerateParcelSource(out, types, union_decl, options);
254 }
255 }
256
257 void Visit(const AidlEnumDeclaration& enum_decl) override {
258 if (!enum_decl.GetParentType()) {
259 out << "// This file is intentionally left blank as placeholder for enum declaration.\n";
260 }
261 }
262 } v(out, types, options);
263 VisitTopDown(v, defined_type);
264 }
265
GenerateHeaderIncludes(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)266 void GenerateHeaderIncludes(CodeWriter& out, const AidlTypenames& types,
267 const AidlDefinedType& defined_type, const Options& options) {
268 // Collect implementation related headers and referenced defined types by recursivly visiting
269 // nested types
270 struct Visitor : AidlVisitor {
271 const AidlTypenames& types;
272 const Options& options;
273 std::set<std::string, HeaderComp> includes;
274 Visitor(const AidlTypenames& types, const Options& options) : types(types), options(options) {}
275
276 // Collect includes for each type reference
277 void Visit(const AidlTypeSpecifier& type) override {
278 auto defined = type.GetDefinedType();
279 if (!defined) return;
280 includes.insert(NdkHeaderFile(*defined, ClassNames::RAW, false /*use_os_sep*/));
281 }
282
283 // Collect implementation-specific includes for each type definition
284 void Visit(const AidlInterface& interface) override {
285 AddCommonHeaders(interface);
286 includes.insert("android/binder_interface_utils.h");
287 if (options.GenLog()) {
288 includes.insert("functional");
289 includes.insert("chrono");
290 includes.insert("sstream");
291 }
292 // For nested interfaces client/server classes are defined in the same header.
293 // So we need includes for client/server class as well.
294 if (interface.GetParentType()) {
295 includes.insert("android/binder_ibinder.h");
296 if (options.GenTraces()) {
297 includes.insert("android/trace.h");
298 }
299 }
300 }
301
302 void Visit(const AidlStructuredParcelable& parcelable) override {
303 AddCommonHeaders(parcelable);
304 includes.insert("android/binder_interface_utils.h");
305 includes.insert("android/binder_parcelable_utils.h");
306 includes.insert("android/binder_to_string.h"); // used by toString()
307 }
308
309 void Visit(const AidlUnionDecl& union_decl) override {
310 AddCommonHeaders(union_decl);
311 includes.insert("android/binder_interface_utils.h");
312 includes.insert("android/binder_parcelable_utils.h");
313 includes.insert("android/binder_to_string.h"); // used by toString()
314 auto union_headers = cpp::UnionWriter::GetHeaders(union_decl);
315 includes.insert(std::begin(union_headers), std::end(union_headers));
316 }
317
318 void Visit(const AidlEnumDeclaration& enum_decl) override {
319 AddCommonHeaders(enum_decl);
320 includes.insert("array");
321 includes.insert("android/binder_enums.h");
322 }
323
324 void AddCommonHeaders(const AidlDefinedType& defined_type) {
325 includes.insert("cstdint");
326 includes.insert("memory");
327 includes.insert("optional");
328 includes.insert("string");
329 includes.insert("vector");
330 if (defined_type.IsSensitiveData()) {
331 includes.insert("android/binder_parcel_platform.h");
332 includes.insert("android/binder_ibinder_platform.h");
333 }
334 }
335 } v(types, options);
336 VisitTopDown(v, defined_type);
337
338 for (const auto& path : v.includes) {
339 out << "#include <" << path << ">\n";
340 }
341 out << "#ifdef BINDER_STABILITY_SUPPORT\n";
342 out << "#include <android/binder_stability.h>\n";
343 out << "#endif // BINDER_STABILITY_SUPPORT\n";
344 out << "\n";
345
346 if (v.includes.count("cassert")) {
347 // TODO(b/31559095) bionic on host should define __assert2
348 out << "#ifndef __BIONIC__\n#define __assert2(a,b,c,d) ((void)0)\n#endif\n\n";
349 }
350 }
351
GenerateClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)352 void GenerateClassDecl(CodeWriter& out, const AidlTypenames& types,
353 const AidlDefinedType& defined_type, const Options& options) {
354 if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
355 GenerateInterfaceClassDecl(out, types, *iface, options);
356 } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
357 GenerateParcelClassDecl(out, types, *parcelable, options);
358 } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
359 GenerateParcelClassDecl(out, types, *union_decl, options);
360 } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
361 GenerateEnumClassDecl(out, types, *enum_decl, options);
362 } else {
363 AIDL_FATAL(defined_type) << "Unrecognized type sent for NDK generation.";
364 }
365 }
366
GenerateSourceIncludes(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & defined_type,const Options & options)367 static void GenerateSourceIncludes(CodeWriter& out, const AidlTypenames& types,
368 const AidlDefinedType& defined_type, const Options& options) {
369 // Once in a .cpp file
370 if (defined_type.GetParentType() != nullptr) {
371 return;
372 }
373
374 const string self_header = NdkHeaderFile(defined_type, ClassNames::RAW, false /*use_os_sep*/);
375 out << "#include \"" << self_header << "\"\n";
376 out << "\n";
377
378 std::set<std::string, HeaderComp> includes = {self_header};
379 includes.insert("android/binder_parcel_utils.h");
380 types.IterateTypes([&](const AidlDefinedType& a_defined_type) {
381 if (a_defined_type.AsInterface() != nullptr) {
382 includes.insert(NdkHeaderFile(a_defined_type, ClassNames::CLIENT, false /*use_os_sep*/));
383 includes.insert(NdkHeaderFile(a_defined_type, ClassNames::SERVER, false /*use_os_sep*/));
384 includes.insert(NdkHeaderFile(a_defined_type, ClassNames::RAW, false /*use_os_sep*/));
385 }
386 });
387
388 struct Visitor : AidlVisitor {
389 bool has_interface = false;
390 void Visit(const AidlInterface&) override { has_interface = true; }
391 } v;
392 VisitTopDown(v, defined_type);
393
394 if (v.has_interface && options.GenLog()) {
395 includes.insert("android/binder_to_string.h");
396 }
397
398 // Emit includes except self_header
399 includes.erase(includes.find(self_header));
400 for (const auto& inc : includes) {
401 out << "#include <" << inc << ">\n";
402 }
403 out << "\n";
404
405 // Emit additional definition for gen_traces
406 if (v.has_interface && options.GenTraces()) {
407 out << "namespace {\n";
408 out << "struct ScopedTrace {\n";
409 out.Indent();
410 out << "inline explicit ScopedTrace(const char* name) { ATrace_beginSection(name); }\n";
411 out << "inline ~ScopedTrace() { ATrace_endSection(); }\n";
412 out.Dedent();
413 out << "};\n";
414 out << "} // namespace\n";
415 out << "\n";
416 }
417 }
418
GenerateConstantDeclarations(CodeWriter & out,const AidlTypenames & types,const AidlDefinedType & type)419 static void GenerateConstantDeclarations(CodeWriter& out, const AidlTypenames& types,
420 const AidlDefinedType& type) {
421 for (const auto& constant : type.GetConstantDeclarations()) {
422 const AidlTypeSpecifier& type = constant->GetType();
423
424 if (type.Signature() == "String") {
425 out << "static const char*";
426 cpp::GenerateDeprecated(out, *constant);
427 out << " " << constant->GetName() << ";\n";
428 } else if (type.Signature() == "float" || type.Signature() == "double") {
429 out << "static constexpr " << NdkNameOf(types, type, StorageMode::STACK) << " ";
430 out << constant->GetName();
431 cpp::GenerateDeprecated(out, *constant);
432 out << " = " << constant->ValueString(ConstantValueDecorator) << ";\n";
433 } else {
434 out << "enum : " << NdkNameOf(types, type, StorageMode::STACK) << " { ";
435 out << constant->GetName();
436 cpp::GenerateDeprecated(out, *constant);
437 out << " = " << constant->ValueString(ConstantValueDecorator) << " };\n";
438 }
439 }
440 }
441
GenerateConstantDefinitions(CodeWriter & out,const AidlDefinedType & interface,const std::string & clazz,const std::string & tmpl_decl="")442 static void GenerateConstantDefinitions(CodeWriter& out, const AidlDefinedType& interface,
443 const std::string& clazz,
444 const std::string& tmpl_decl = "") {
445 for (const auto& constant : interface.GetConstantDeclarations()) {
446 const AidlConstantValue& value = constant->GetValue();
447 AIDL_FATAL_IF(value.GetType() == AidlConstantValue::Type::UNARY ||
448 value.GetType() == AidlConstantValue::Type::BINARY,
449 value);
450 if (value.GetType() == AidlConstantValue::Type::STRING) {
451 out << tmpl_decl;
452 out << "const char* " << clazz << "::" << constant->GetName() << " = "
453 << constant->ValueString(ConstantValueDecorator) << ";\n";
454 }
455 }
456 }
457
GenerateSource(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)458 void GenerateSource(CodeWriter& out, const AidlTypenames& types, const AidlInterface& defined_type,
459 const Options& options) {
460 GenerateSourceIncludes(out, types, defined_type, options);
461 EnterNdkNamespace(out, defined_type);
462 GenerateClassSource(out, types, defined_type, options);
463 GenerateClientSource(out, types, defined_type, options);
464 GenerateServerSource(out, types, defined_type, options);
465 GenerateInterfaceSource(out, types, defined_type, options);
466 LeaveNdkNamespace(out, defined_type);
467 }
468
MethodId(const AidlMethod & m)469 static std::string MethodId(const AidlMethod& m) {
470 return "(FIRST_CALL_TRANSACTION + " + std::to_string(m.GetId()) + " /*" + m.GetName() + "*/)";
471 }
472
GenerateClientMethodDefinition(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const AidlMethod & method,const Options & options)473 static void GenerateClientMethodDefinition(CodeWriter& out, const AidlTypenames& types,
474 const AidlInterface& defined_type,
475 const AidlMethod& method, const Options& options) {
476 const std::string q_name = GetQualifiedName(defined_type, ClassNames::CLIENT);
477 const std::string clazz = ClassName(defined_type, ClassNames::CLIENT);
478
479 out << NdkMethodDecl(types, method, q_name) << " {\n";
480 out.Indent();
481 out << "binder_status_t _aidl_ret_status = STATUS_OK;\n";
482 out << "::ndk::ScopedAStatus _aidl_status;\n";
483
484 if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
485 out << "const std::lock_guard<std::mutex> lock(" << kCachedHashMutex << ");\n";
486 out << "if (" << kCachedHash << " != \"-1\") {\n";
487 out.Indent();
488 out << "*_aidl_return = " << kCachedHash << ";\n"
489 << "_aidl_status.set(AStatus_fromStatus(_aidl_ret_status));\n"
490 << "return _aidl_status;\n";
491 out.Dedent();
492 out << "}\n";
493 } else if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
494 out << "if (" << kCachedVersion << " != -1) {\n";
495 out.Indent();
496 out << "*_aidl_return = " << kCachedVersion << ";\n"
497 << "_aidl_status.set(AStatus_fromStatus(_aidl_ret_status));\n"
498 << "return _aidl_status;\n";
499 out.Dedent();
500 out << "}\n";
501 }
502 out << "::ndk::ScopedAParcel _aidl_in;\n";
503 out << "::ndk::ScopedAParcel _aidl_out;\n";
504 out << "\n";
505
506 if (options.GenLog()) {
507 out << cpp::GenLogBeforeExecute(q_name, method, false /* isServer */, true /* isNdk */);
508 }
509 if (options.GenTraces()) {
510 out << "ScopedTrace _aidl_trace(\"AIDL::" << to_string(options.TargetLanguage())
511 << "::" << ClassName(defined_type, ClassNames::INTERFACE) << "::" << method.GetName()
512 << "::client\");\n";
513 }
514
515 out << "_aidl_ret_status = AIBinder_prepareTransaction(asBinder().get(), _aidl_in.getR());\n";
516 if (defined_type.IsSensitiveData()) {
517 out << "AParcel_markSensitive(_aidl_in.get());\n";
518 }
519 StatusCheckGoto(out);
520
521 for (const auto& arg : method.GetArguments()) {
522 const std::string var_name = cpp::BuildVarName(*arg);
523
524 if (arg->IsIn()) {
525 out << "_aidl_ret_status = ";
526 const std::string prefix = (arg->IsOut() ? "*" : "");
527 WriteToParcelFor({out, types, arg->GetType(), "_aidl_in.get()", prefix + var_name});
528 out << ";\n";
529 StatusCheckGoto(out);
530 } else if (arg->IsOut() && arg->GetType().IsDynamicArray()) {
531 out << "_aidl_ret_status = ::ndk::AParcel_writeVectorSize(_aidl_in.get(), *" << var_name
532 << ");\n";
533 StatusCheckGoto(out);
534 }
535 }
536 out << "_aidl_ret_status = AIBinder_transact(\n";
537 out.Indent();
538 out << "asBinder().get(),\n";
539 out << MethodId(method) << ",\n";
540 out << "_aidl_in.getR(),\n";
541 out << "_aidl_out.getR(),\n";
542
543 std::vector<std::string> flags;
544 if (method.IsOneway()) flags.push_back("FLAG_ONEWAY");
545 if (defined_type.IsSensitiveData()) flags.push_back("FLAG_CLEAR_BUF");
546 out << (flags.empty() ? "0" : base::Join(flags, " | ")) << "\n";
547
548 out << "#ifdef BINDER_STABILITY_SUPPORT\n";
549 out << "| FLAG_PRIVATE_LOCAL\n";
550 out << "#endif // BINDER_STABILITY_SUPPORT\n";
551 out << ");\n";
552 out.Dedent();
553
554 // If the method is not implmented in the server side but the client has
555 // provided the default implementation, call it instead of failing hard.
556 const std::string iface = ClassName(defined_type, ClassNames::INTERFACE);
557 out << "if (_aidl_ret_status == STATUS_UNKNOWN_TRANSACTION && ";
558 out << iface << "::getDefaultImpl()) {\n";
559 out.Indent();
560 out << "_aidl_status = " << iface << "::getDefaultImpl()->" << method.GetName() << "(";
561 out << NdkArgList(types, method, FormatArgNameOnly) << ");\n";
562 out << "goto _aidl_status_return;\n";
563 out.Dedent();
564 out << "}\n";
565
566 StatusCheckGoto(out);
567
568 if (!method.IsOneway()) {
569 out << "_aidl_ret_status = AParcel_readStatusHeader(_aidl_out.get(), _aidl_status.getR());\n";
570 StatusCheckGoto(out);
571
572 out << "if (!AStatus_isOk(_aidl_status.get())) goto _aidl_status_return;\n";
573 }
574
575 if (method.GetType().GetName() != "void") {
576 out << "_aidl_ret_status = ";
577 ReadFromParcelFor({out, types, method.GetType(), "_aidl_out.get()", "_aidl_return"});
578 out << ";\n";
579 StatusCheckGoto(out);
580 if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
581 out << kCachedHash << " = *_aidl_return;\n";
582 } else if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
583 out << kCachedVersion << " = *_aidl_return;\n";
584 }
585 }
586 for (const AidlArgument* arg : method.GetOutArguments()) {
587 out << "_aidl_ret_status = ";
588 ReadFromParcelFor({out, types, arg->GetType(), "_aidl_out.get()", cpp::BuildVarName(*arg)});
589 out << ";\n";
590 StatusCheckGoto(out);
591 }
592
593 out << "_aidl_error:\n";
594 out << "_aidl_status.set(AStatus_fromStatus(_aidl_ret_status));\n";
595 out << "_aidl_status_return:\n";
596 if (options.GenLog()) {
597 out << cpp::GenLogAfterExecute(q_name, defined_type, method, "_aidl_status", "_aidl_return",
598 false /* isServer */, true /* isNdk */);
599 }
600
601 out << "return _aidl_status;\n";
602 out.Dedent();
603 out << "}\n";
604 }
605
GenerateServerCaseDefinition(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const AidlMethod & method,const Options & options)606 static void GenerateServerCaseDefinition(CodeWriter& out, const AidlTypenames& types,
607 const AidlInterface& defined_type,
608 const AidlMethod& method, const Options& options) {
609 const string q_name = GetQualifiedName(defined_type, ClassNames::SERVER);
610
611 out << "case " << MethodId(method) << ": {\n";
612 out.Indent();
613
614 if (defined_type.EnforceExpression() || method.GetType().EnforceExpression()) {
615 out.Write("#error Permission checks not implemented for the ndk backend\n");
616 }
617
618 for (const auto& arg : method.GetArguments()) {
619 out << NdkNameOf(types, arg->GetType(), StorageMode::STACK) << " " << cpp::BuildVarName(*arg)
620 << ";\n";
621 }
622 if (method.GetType().GetName() != "void") {
623 out << NdkNameOf(types, method.GetType(), StorageMode::STACK) << " _aidl_return;\n";
624 }
625 out << "\n";
626 if (options.GenTraces()) {
627 out << "ScopedTrace _aidl_trace(\"AIDL::" << to_string(options.TargetLanguage())
628 << "::" << ClassName(defined_type, ClassNames::INTERFACE) << "::" << method.GetName()
629 << "::server\");\n";
630 }
631
632 for (const auto& arg : method.GetArguments()) {
633 const std::string var_name = cpp::BuildVarName(*arg);
634
635 if (arg->IsIn()) {
636 out << "_aidl_ret_status = ";
637 ReadFromParcelFor({out, types, arg->GetType(), "_aidl_in", "&" + var_name});
638 out << ";\n";
639 StatusCheckBreak(out);
640 } else if (arg->IsOut() && arg->GetType().IsDynamicArray()) {
641 out << "_aidl_ret_status = ::ndk::AParcel_resizeVector(_aidl_in, &" << var_name << ");\n";
642 StatusCheckBreak(out);
643 }
644 }
645 if (options.GenLog()) {
646 out << cpp::GenLogBeforeExecute(q_name, method, true /* isServer */, true /* isNdk */);
647 }
648 out << "::ndk::ScopedAStatus _aidl_status = _aidl_impl->" << method.GetName() << "("
649 << NdkArgList(types, method, FormatArgForCall) << ");\n";
650
651 if (options.GenLog()) {
652 out << cpp::GenLogAfterExecute(q_name, defined_type, method, "_aidl_status", "_aidl_return",
653 true /* isServer */, true /* isNdk */);
654 }
655 if (method.IsOneway()) {
656 // For a oneway transaction, the kernel will have already returned a result. This is for the
657 // in-process case when a oneway transaction is parceled/unparceled in the same process.
658 out << "_aidl_ret_status = STATUS_OK;\n";
659 } else {
660 out << "_aidl_ret_status = AParcel_writeStatusHeader(_aidl_out, _aidl_status.get());\n";
661 StatusCheckBreak(out);
662
663 out << "if (!AStatus_isOk(_aidl_status.get())) break;\n\n";
664
665 if (method.GetType().GetName() != "void") {
666 out << "_aidl_ret_status = ";
667 WriteToParcelFor({out, types, method.GetType(), "_aidl_out", "_aidl_return"});
668 out << ";\n";
669 StatusCheckBreak(out);
670 }
671 for (const AidlArgument* arg : method.GetOutArguments()) {
672 out << "_aidl_ret_status = ";
673 WriteToParcelFor({out, types, arg->GetType(), "_aidl_out", cpp::BuildVarName(*arg)});
674 out << ";\n";
675 StatusCheckBreak(out);
676 }
677 }
678 out << "break;\n";
679 out.Dedent();
680 out << "}\n";
681 }
682
OnTransactFuncName(const AidlInterface & interface)683 static string OnTransactFuncName(const AidlInterface& interface) {
684 string name = interface.GetCanonicalName();
685 std::replace(name.begin(), name.end(), '.', '_');
686 return "_aidl_" + name + "_onTransact";
687 }
688
GlobalClassVarName(const AidlInterface & interface)689 static string GlobalClassVarName(const AidlInterface& interface) {
690 string name = interface.GetCanonicalName();
691 std::replace(name.begin(), name.end(), '.', '_');
692 return "_g_aidl_" + name + "_clazz";
693 }
694
GenerateClassSource(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)695 void GenerateClassSource(CodeWriter& out, const AidlTypenames& types,
696 const AidlInterface& defined_type, const Options& options) {
697 const std::string i_name = GetQualifiedName(defined_type, ClassNames::INTERFACE);
698 const std::string q_name = GetQualifiedName(defined_type, ClassNames::SERVER);
699
700 const string on_transact = OnTransactFuncName(defined_type);
701 bool deprecated = defined_type.IsDeprecated() ||
702 std::any_of(defined_type.GetMethods().begin(), defined_type.GetMethods().end(),
703 [](const auto& m) { return m->IsDeprecated(); });
704 if (deprecated) {
705 out << "#pragma clang diagnostic push\n";
706 out << "#pragma clang diagnostic ignored \"-Wdeprecated\"\n";
707 }
708 out << "static binder_status_t " << on_transact
709 << "(AIBinder* _aidl_binder, transaction_code_t _aidl_code, const AParcel* _aidl_in, "
710 "AParcel* _aidl_out) {\n";
711 out.Indent();
712 out << "(void)_aidl_in;\n";
713 out << "(void)_aidl_out;\n";
714 out << "binder_status_t _aidl_ret_status = STATUS_UNKNOWN_TRANSACTION;\n";
715 if (!defined_type.GetMethods().empty()) {
716 // we know this cast is valid because this method is only called by the ICInterface
717 // AIBinder_Class object which is associated with this class.
718 out << "std::shared_ptr<" << q_name << "> _aidl_impl = std::static_pointer_cast<" << q_name
719 << ">(::ndk::ICInterface::asInterface(_aidl_binder));\n";
720 out << "switch (_aidl_code) {\n";
721 out.Indent();
722 for (const auto& method : defined_type.GetMethods()) {
723 GenerateServerCaseDefinition(out, types, defined_type, *method, options);
724 }
725 out.Dedent();
726 out << "}\n";
727 } else {
728 out << "(void)_aidl_binder;\n";
729 out << "(void)_aidl_code;\n";
730 }
731 out << "return _aidl_ret_status;\n";
732 out.Dedent();
733 out << "}\n\n";
734
735 out << "static AIBinder_Class* " << GlobalClassVarName(defined_type)
736 << " = ::ndk::ICInterface::defineClass(" << i_name << "::" << kDescriptor << ", "
737 << on_transact << ");\n\n";
738 if (deprecated) {
739 out << "#pragma clang diagnostic pop\n";
740 }
741 }
742
GenerateClientSource(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)743 void GenerateClientSource(CodeWriter& out, const AidlTypenames& types,
744 const AidlInterface& defined_type, const Options& options) {
745 const std::string q_name = GetQualifiedName(defined_type, ClassNames::CLIENT);
746 const std::string clazz = ClassName(defined_type, ClassNames::CLIENT);
747
748 out << q_name << "::" << clazz << "(const ::ndk::SpAIBinder& binder) : BpCInterface(binder) {}\n";
749 out << q_name << "::~" << clazz << "() {}\n";
750 if (options.GenLog()) {
751 out << "std::function<void(const " << q_name << "::TransactionLog&)> " << q_name
752 << "::logFunc;\n";
753 }
754 out << "\n";
755 for (const auto& method : defined_type.GetMethods()) {
756 GenerateClientMethodDefinition(out, types, defined_type, *method, options);
757 }
758 }
759
GenerateServerSource(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)760 void GenerateServerSource(CodeWriter& out, const AidlTypenames& types,
761 const AidlInterface& defined_type, const Options& options) {
762 const std::string q_name = GetQualifiedName(defined_type, ClassNames::SERVER);
763 const std::string clazz = ClassName(defined_type, ClassNames::SERVER);
764 const std::string iface = ClassName(defined_type, ClassNames::INTERFACE);
765
766 out << "// Source for " << clazz << "\n";
767 out << q_name << "::" << clazz << "() {}\n";
768 out << q_name << "::~" << clazz << "() {}\n";
769 if (options.GenLog()) {
770 out << "std::function<void(const " << q_name << "::TransactionLog&)> " << q_name
771 << "::logFunc;\n";
772 }
773 out << "::ndk::SpAIBinder " << q_name << "::createBinder() {\n";
774 out.Indent();
775 out << "AIBinder* binder = AIBinder_new(" << GlobalClassVarName(defined_type)
776 << ", static_cast<void*>(this));\n";
777
778 out << "#ifdef BINDER_STABILITY_SUPPORT\n";
779 if (defined_type.IsVintfStability()) {
780 out << "AIBinder_markVintfStability(binder);\n";
781 } else {
782 out << "AIBinder_markCompilationUnitStability(binder);\n";
783 }
784 out << "#endif // BINDER_STABILITY_SUPPORT\n";
785
786 out << "return ::ndk::SpAIBinder(binder);\n";
787 out.Dedent();
788 out << "}\n";
789
790 // Implement the meta methods
791 for (const auto& method : defined_type.GetMethods()) {
792 if (method->IsUserDefined()) {
793 continue;
794 }
795 if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
796 out << NdkMethodDecl(types, *method, q_name) << " {\n";
797 out.Indent();
798 out << "*_aidl_return = " << iface << "::" << kVersion << ";\n";
799 out << "return ::ndk::ScopedAStatus(AStatus_newOk());\n";
800 out.Dedent();
801 out << "}\n";
802 }
803 if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
804 out << NdkMethodDecl(types, *method, q_name) << " {\n";
805 out.Indent();
806 out << "*_aidl_return = " << iface << "::" << kHash << ";\n";
807 out << "return ::ndk::ScopedAStatus(AStatus_newOk());\n";
808 out.Dedent();
809 out << "}\n";
810 }
811 }
812 }
GenerateInterfaceSource(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)813 void GenerateInterfaceSource(CodeWriter& out, const AidlTypenames& types,
814 const AidlInterface& defined_type, const Options& options) {
815 const std::string q_name = GetQualifiedName(defined_type, ClassNames::INTERFACE);
816 const std::string clazz = ClassName(defined_type, ClassNames::INTERFACE);
817 const std::string bp_clazz = ClassName(defined_type, ClassNames::CLIENT);
818
819 out << "// Source for " << clazz << "\n";
820 out << "const char* " << q_name << "::" << kDescriptor << " = \"" << defined_type.GetDescriptor()
821 << "\";\n";
822 out << q_name << "::" << clazz << "() {}\n";
823 out << q_name << "::~" << clazz << "() {}\n";
824 out << "\n";
825 GenerateConstantDefinitions(out, defined_type, q_name);
826 out << "\n";
827
828 out << "std::shared_ptr<" << q_name << "> " << q_name
829 << "::fromBinder(const ::ndk::SpAIBinder& binder) {\n";
830 out.Indent();
831 out << "if (!AIBinder_associateClass(binder.get(), " << GlobalClassVarName(defined_type)
832 << ")) { return nullptr; }\n";
833 out << "std::shared_ptr<::ndk::ICInterface> interface = "
834 "::ndk::ICInterface::asInterface(binder.get());\n";
835 out << "if (interface) {\n";
836 out.Indent();
837 out << "return std::static_pointer_cast<" << clazz << ">(interface);\n";
838 out.Dedent();
839 out << "}\n";
840 out << "return ::ndk::SharedRefBase::make<" << GetQualifiedName(defined_type, ClassNames::CLIENT)
841 << ">(binder);\n";
842 out.Dedent();
843 out << "}\n\n";
844
845 out << "binder_status_t " << q_name << "::writeToParcel(AParcel* parcel, const std::shared_ptr<"
846 << clazz << ">& instance) {\n";
847 out.Indent();
848 out << "return AParcel_writeStrongBinder(parcel, instance ? instance->asBinder().get() : "
849 "nullptr);\n";
850 out.Dedent();
851 out << "}\n";
852
853 out << "binder_status_t " << q_name << "::readFromParcel(const AParcel* parcel, std::shared_ptr<"
854 << clazz << ">* instance) {\n";
855 out.Indent();
856 out << "::ndk::SpAIBinder binder;\n";
857 out << "binder_status_t status = AParcel_readStrongBinder(parcel, binder.getR());\n";
858 out << "if (status != STATUS_OK) return status;\n";
859 out << "*instance = " << clazz << "::fromBinder(binder);\n";
860 out << "return STATUS_OK;\n";
861 out.Dedent();
862 out << "}\n";
863
864 // defintion for static member setDefaultImpl
865 out << "bool " << q_name << "::setDefaultImpl(const std::shared_ptr<" << clazz << ">& impl) {\n";
866 out.Indent();
867 out << "// Only one user of this interface can use this function\n";
868 out << "// at a time. This is a heuristic to detect if two different\n";
869 out << "// users in the same process use this function.\n";
870 out << "assert(!" << clazz << "::default_impl);\n";
871 out << "if (impl) {\n";
872 out.Indent();
873 out << clazz << "::default_impl = impl;\n";
874 out << "return true;\n";
875 out.Dedent();
876 out << "}\n";
877 out << "return false;\n";
878 out.Dedent();
879 out << "}\n";
880
881 // definition for static member getDefaultImpl
882 out << "const std::shared_ptr<" << q_name << ">& " << q_name << "::getDefaultImpl() {\n";
883 out.Indent();
884 out << "return " << clazz << "::default_impl;\n";
885 out.Dedent();
886 out << "}\n";
887
888 // definition for the static field default_impl
889 out << "std::shared_ptr<" << q_name << "> " << q_name << "::default_impl = nullptr;\n";
890
891 // default implementation for the <Name>Default class members
892 const std::string defaultClazz = q_name + "Default";
893 for (const auto& method : defined_type.GetMethods()) {
894 if (method->IsUserDefined()) {
895 out << "::ndk::ScopedAStatus " << defaultClazz << "::" << method->GetName() << "("
896 << NdkArgList(types, *method, FormatArgNameUnused) << ") {\n";
897 out.Indent();
898 out << "::ndk::ScopedAStatus _aidl_status;\n";
899 out << "_aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));\n";
900 out << "return _aidl_status;\n";
901 out.Dedent();
902 out << "}\n";
903 } else {
904 if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
905 out << "::ndk::ScopedAStatus " << defaultClazz << "::" << method->GetName() << "("
906 << "int32_t* _aidl_return) {\n";
907 out.Indent();
908 out << "*_aidl_return = 0;\n";
909 out << "return ::ndk::ScopedAStatus(AStatus_newOk());\n";
910 out.Dedent();
911 out << "}\n";
912 }
913 if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
914 out << "::ndk::ScopedAStatus " << defaultClazz << "::" << method->GetName() << "("
915 << "std::string* _aidl_return) {\n";
916 out.Indent();
917 out << "*_aidl_return = \"\";\n";
918 out << "return ::ndk::ScopedAStatus(AStatus_newOk());\n";
919 out.Dedent();
920 out << "}\n";
921 }
922 }
923 }
924
925 out << "::ndk::SpAIBinder " << defaultClazz << "::asBinder() {\n";
926 out.Indent();
927 out << "return ::ndk::SpAIBinder();\n";
928 out.Dedent();
929 out << "}\n";
930
931 out << "bool " << defaultClazz << "::isRemote() {\n";
932 out.Indent();
933 out << "return false;\n";
934 out.Dedent();
935 out << "}\n";
936 }
937
GenerateClientClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)938 void GenerateClientClassDecl(CodeWriter& out, const AidlTypenames& types,
939 const AidlInterface& defined_type, const Options& options) {
940 const std::string clazz = ClassName(defined_type, ClassNames::CLIENT);
941
942 out << "class";
943 cpp::GenerateDeprecated(out, defined_type);
944 out << " " << clazz << " : public ::ndk::BpCInterface<"
945 << ClassName(defined_type, ClassNames::INTERFACE) << "> {\n";
946 out << "public:\n";
947 out.Indent();
948 out << "explicit " << clazz << "(const ::ndk::SpAIBinder& binder);\n";
949 out << "virtual ~" << clazz << "();\n";
950 out << "\n";
951 for (const auto& method : defined_type.GetMethods()) {
952 out << NdkMethodDecl(types, *method) << " override";
953 cpp::GenerateDeprecated(out, *method);
954 out << ";\n";
955 }
956
957 if (options.Version() > 0) {
958 out << "int32_t " << kCachedVersion << " = -1;\n";
959 }
960
961 if (!options.Hash().empty()) {
962 out << "std::string " << kCachedHash << " = \"-1\";\n";
963 out << "std::mutex " << kCachedHashMutex << ";\n";
964 }
965 if (options.GenLog()) {
966 out << cpp::kTransactionLogStruct;
967 out << "static std::function<void(const TransactionLog&)> logFunc;\n";
968 }
969 out.Dedent();
970 out << "};\n";
971 }
972
GenerateClientHeader(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)973 void GenerateClientHeader(CodeWriter& out, const AidlTypenames& types,
974 const AidlInterface& defined_type, const Options& options) {
975 out << "#pragma once\n\n";
976 out << "#include \"" << NdkHeaderFile(defined_type, ClassNames::RAW, false /*use_os_sep*/)
977 << "\"\n";
978 out << "\n";
979 out << "#include <android/binder_ibinder.h>\n";
980 if (options.GenLog()) {
981 out << "#include <functional>\n";
982 out << "#include <chrono>\n";
983 out << "#include <sstream>\n";
984 }
985 if (options.GenTraces()) {
986 out << "#include <android/trace.h>\n";
987 }
988 out << "\n";
989 EnterNdkNamespace(out, defined_type);
990 GenerateClientClassDecl(out, types, defined_type, options);
991 LeaveNdkNamespace(out, defined_type);
992 }
993
GenerateDelegatorClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)994 void GenerateDelegatorClassDecl(CodeWriter& out, const AidlTypenames& types,
995 const AidlInterface& defined_type, const Options& options) {
996 const std::string clazz = ClassName(defined_type, ClassNames::DELEGATOR_IMPL);
997 const std::string iface = ClassName(defined_type, ClassNames::INTERFACE);
998 const std::string bn_name = ClassName(defined_type, ClassNames::SERVER);
999 const std::string kDelegateImplVarName = "_impl";
1000 const std::string kStatusType = "::ndk::ScopedAStatus";
1001
1002 out << "class";
1003 cpp::GenerateDeprecated(out, defined_type);
1004 out << " " << clazz << " : public " << bn_name << " {\n";
1005 out << "public:\n";
1006 out.Indent();
1007 out << "explicit " << clazz << "(const std::shared_ptr<" << iface << "> &impl)"
1008 << " : " << kDelegateImplVarName << "(impl) {\n";
1009 if (options.Version() > 0) {
1010 // TODO(b/222347502) If we need to support mismatched versions of delegator and
1011 // impl, this check will be removed. The NDK backend can't override the
1012 // getInterface* meta methods because they are marked "final". Removing
1013 // "final" changes the ABI and breaks prebuilts.
1014 out << " int32_t _impl_ver = 0;\n";
1015 out << " if (!impl->" << kGetInterfaceVersion << "(&_impl_ver).isOk()) {;\n";
1016 out << " __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, \"Delegator failed to get "
1017 "version of the implementation.\");\n";
1018 out << " }\n";
1019 out << " if (_impl_ver != " << iface << "::" << kVersion << ") {\n";
1020 out << " __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, \"Mismatched versions of "
1021 "delegator and implementation is not allowed.\");\n";
1022 out << " }\n";
1023 }
1024 out << "}\n\n";
1025 for (const auto& method : defined_type.GetMethods()) {
1026 if (method->IsUserDefined()) {
1027 out << kStatusType << " " << method->GetName() << "("
1028 << NdkArgList(types, *method, FormatArgForDecl) << ") override";
1029 cpp::GenerateDeprecated(out, *method);
1030 out << " {\n"
1031 << " return " << kDelegateImplVarName << "->" << method->GetName() << "("
1032 << NdkArgList(types, *method, FormatArgNameOnly) << ");\n";
1033 out << "}\n";
1034 }
1035 }
1036 out.Dedent();
1037 out << "protected:\n";
1038 out.Indent();
1039 out.Dedent();
1040 out << "private:\n";
1041 out.Indent();
1042 out << "std::shared_ptr<" << iface << "> " << kDelegateImplVarName << ";\n";
1043 out.Dedent();
1044 out << "};\n\n";
1045 }
1046
GenerateServerClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)1047 void GenerateServerClassDecl(CodeWriter& out, const AidlTypenames& types,
1048 const AidlInterface& defined_type, const Options& options) {
1049 const std::string clazz = ClassName(defined_type, ClassNames::SERVER);
1050 const std::string iface = ClassName(defined_type, ClassNames::INTERFACE);
1051
1052 out << "class";
1053 cpp::GenerateDeprecated(out, defined_type);
1054 out << " " << clazz << " : public ::ndk::BnCInterface<" << iface << "> {\n";
1055 out << "public:\n";
1056 out.Indent();
1057 out << clazz << "();\n";
1058 out << "virtual ~" << clazz << "();\n";
1059
1060 // Declare the meta methods
1061 for (const auto& method : defined_type.GetMethods()) {
1062 if (method->IsUserDefined()) {
1063 continue;
1064 }
1065 if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1066 out << NdkMethodDecl(types, *method) << " final;\n";
1067 } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1068 out << NdkMethodDecl(types, *method) << " final;\n";
1069 } else {
1070 AIDL_FATAL(defined_type) << "Meta method '" << method->GetName() << "' is unimplemented.";
1071 }
1072 }
1073 if (options.GenLog()) {
1074 out << cpp::kTransactionLogStruct;
1075 out << "static std::function<void(const TransactionLog&)> logFunc;\n";
1076 }
1077 out.Dedent();
1078 out << "protected:\n";
1079 out.Indent();
1080 out << "::ndk::SpAIBinder createBinder() override;\n";
1081 out.Dedent();
1082 out << "private:\n";
1083 out.Indent();
1084 out.Dedent();
1085 out << "};\n";
1086 }
1087
GenerateServerHeader(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)1088 void GenerateServerHeader(CodeWriter& out, const AidlTypenames& types,
1089 const AidlInterface& defined_type, const Options& options) {
1090 out << "#pragma once\n\n";
1091 out << "#include \"" << NdkHeaderFile(defined_type, ClassNames::RAW, false /*use_os_sep*/)
1092 << "\"\n";
1093 out << "\n";
1094 out << "#include <android/binder_ibinder.h>\n";
1095 // Needed for *Delegator classes while delegator version is required to be
1096 // the same as the implementation version
1097 // TODO(b/222347502) If we ever need to support mismatched versions of delegator and
1098 // impl, this include can be removed.
1099 out << "#include <cassert>\n\n";
1100 // TODO(b/31559095) bionic on host should define __assert2
1101 out << "#ifndef __BIONIC__\n#ifndef __assert2\n#define __assert2(a,b,c,d) "
1102 "((void)0)\n#endif\n#endif\n";
1103 out << "\n";
1104 EnterNdkNamespace(out, defined_type);
1105 GenerateServerClassDecl(out, types, defined_type, options);
1106 GenerateDelegatorClassDecl(out, types, defined_type, options);
1107 LeaveNdkNamespace(out, defined_type);
1108 }
1109
GenerateInterfaceClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlInterface & defined_type,const Options & options)1110 void GenerateInterfaceClassDecl(CodeWriter& out, const AidlTypenames& types,
1111 const AidlInterface& defined_type, const Options& options) {
1112 const std::string clazz = ClassName(defined_type, ClassNames::INTERFACE);
1113 out << "class " << ClassName(defined_type, ClassNames::DELEGATOR_IMPL) << ";\n\n";
1114 out << "class";
1115 cpp::GenerateDeprecated(out, defined_type);
1116 out << " " << clazz << " : public ::ndk::ICInterface {\n";
1117 out << "public:\n";
1118 out.Indent();
1119 out << "typedef " << ClassName(defined_type, ClassNames::DELEGATOR_IMPL)
1120 << " DefaultDelegator;\n";
1121 out << "static const char* " << kDescriptor << ";\n";
1122 out << clazz << "();\n";
1123 out << "virtual ~" << clazz << "();\n";
1124 out << "\n";
1125 GenerateNestedTypeDecls(out, types, defined_type, options);
1126 GenerateConstantDeclarations(out, types, defined_type);
1127 if (options.Version() > 0) {
1128 out << "static const int32_t " << kVersion << " = " << std::to_string(options.Version())
1129 << ";\n";
1130 }
1131 if (!options.Hash().empty()) {
1132 out << "static inline const std::string " << kHash << " = \"" << options.Hash() << "\";\n";
1133 }
1134 for (const auto& method : defined_type.GetMethods()) {
1135 if (!method->IsUserDefined()) {
1136 continue;
1137 }
1138 out << "static constexpr uint32_t TRANSACTION_" << method->GetName() << " = "
1139 << "FIRST_CALL_TRANSACTION + " << std::to_string(method->GetId()) << ";\n";
1140 }
1141 out << "\n";
1142 out << "static std::shared_ptr<" << clazz << "> fromBinder(const ::ndk::SpAIBinder& binder);\n";
1143 out << "static binder_status_t writeToParcel(AParcel* parcel, const std::shared_ptr<" << clazz
1144 << ">& instance);";
1145 out << "\n";
1146 out << "static binder_status_t readFromParcel(const AParcel* parcel, std::shared_ptr<" << clazz
1147 << ">* instance);";
1148 out << "\n";
1149 out << "static bool setDefaultImpl(const std::shared_ptr<" << clazz << ">& impl);";
1150 out << "\n";
1151 out << "static const std::shared_ptr<" << clazz << ">& getDefaultImpl();";
1152 out << "\n";
1153 for (const auto& method : defined_type.GetMethods()) {
1154 out << "virtual " << NdkMethodDecl(types, *method);
1155 cpp::GenerateDeprecated(out, *method);
1156 out << " = 0;\n";
1157 }
1158 out.Dedent();
1159 out << "private:\n";
1160 out.Indent();
1161 out << "static std::shared_ptr<" << clazz << "> default_impl;\n";
1162 out.Dedent();
1163 out << "};\n";
1164
1165 const std::string defaultClazz = clazz + "Default";
1166 out << "class";
1167 cpp::GenerateDeprecated(out, defined_type);
1168 out << " " << defaultClazz << " : public " << clazz << " {\n";
1169 out << "public:\n";
1170 out.Indent();
1171 for (const auto& method : defined_type.GetMethods()) {
1172 if (method->IsUserDefined()) {
1173 out << NdkMethodDecl(types, *method) << " override";
1174 cpp::GenerateDeprecated(out, *method);
1175 out << ";\n";
1176 } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1177 out << NdkMethodDecl(types, *method) << " override;\n";
1178 } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1179 out << NdkMethodDecl(types, *method) << " override;\n";
1180 }
1181 }
1182 out << "::ndk::SpAIBinder asBinder() override;\n";
1183 out << "bool isRemote() override;\n";
1184 out.Dedent();
1185 out << "};\n";
1186
1187 // When an interface is nested, every class should be defined together here
1188 // because we don't have separate headers for them.
1189 // (e.g. IFoo, IFooDefault, BpFoo, BnFoo, IFooDelegator)
1190 if (defined_type.GetParentType()) {
1191 GenerateClientClassDecl(out, types, defined_type, options);
1192 GenerateServerClassDecl(out, types, defined_type, options);
1193 }
1194 }
1195
GenerateParcelClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlStructuredParcelable & defined_type,const Options & options)1196 void GenerateParcelClassDecl(CodeWriter& out, const AidlTypenames& types,
1197 const AidlStructuredParcelable& defined_type, const Options& options) {
1198 const std::string clazz = ClassName(defined_type, ClassNames::RAW);
1199
1200 cpp::ClangDiagnosticIgnoreDeprecated guard(out, cpp::HasDeprecatedField(defined_type));
1201 out << cpp::TemplateDecl(defined_type);
1202 out << "class";
1203 cpp::GenerateDeprecated(out, defined_type);
1204 out << " " << clazz << " {\n";
1205 out << "public:\n";
1206 out.Indent();
1207 if (defined_type.IsFixedSize()) {
1208 out << "typedef std::true_type fixed_size;\n";
1209 } else {
1210 out << "typedef std::false_type fixed_size;\n";
1211 }
1212 out << "static const char* descriptor;\n";
1213 out << "\n";
1214 GenerateNestedTypeDecls(out, types, defined_type, options);
1215 for (const auto& variable : defined_type.GetFields()) {
1216 const auto& type = variable->GetType();
1217 std::string cpp_type = NdkNameOf(types, type, StorageMode::STACK);
1218 out << cpp_type;
1219 cpp::GenerateDeprecated(out, *variable);
1220 out << " " << variable->GetName();
1221 if (defined_type.IsFixedSize()) {
1222 int alignment = cpp::AlignmentOf(type, types);
1223 if (alignment > 0) {
1224 out << " __attribute__((aligned (" << std::to_string(alignment) << ")))";
1225 }
1226 }
1227 if (variable->GetDefaultValue()) {
1228 out << " = " << variable->ValueString(ConstantValueDecorator);
1229 } else {
1230 // Some types needs to be explicitly initialized even when no default value is set.
1231 // - ParcelableHolder should be initialized with stability.
1232 // - enum should be zero initialized, otherwise the value will be indeterminate
1233 // - fixed-size arrays should be initialized, otherwise the value will be indeterminate
1234 if (type.GetName() == "ParcelableHolder") {
1235 if (defined_type.IsVintfStability()) {
1236 out << "{::ndk::STABILITY_VINTF}";
1237 } else {
1238 out << "{::ndk::STABILITY_LOCAL}";
1239 }
1240 } else if (types.GetEnumDeclaration(type) && !type.IsArray()) {
1241 out << " = " << cpp_type << "(0)";
1242 } else if (type.IsFixedSizeArray() && !type.IsNullable()) {
1243 out << " = {{}}";
1244 }
1245 }
1246 out << ";\n";
1247 }
1248 out << "\n";
1249 out << "binder_status_t readFromParcel(const AParcel* parcel);\n";
1250 out << "binder_status_t writeToParcel(AParcel* parcel) const;\n";
1251 out << "\n";
1252
1253 cpp::GenerateParcelableComparisonOperators(out, defined_type);
1254
1255 out << "static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::"
1256 << (defined_type.IsVintfStability() ? "STABILITY_VINTF" : "STABILITY_LOCAL") << ";\n";
1257
1258 GenerateConstantDeclarations(out, types, defined_type);
1259 cpp::GenerateToString(out, defined_type);
1260
1261 out.Dedent();
1262 out << "};\n";
1263 }
1264
GenerateParcelSource(CodeWriter & out,const AidlTypenames & types,const AidlStructuredParcelable & defined_type,const Options & options)1265 void GenerateParcelSource(CodeWriter& out, const AidlTypenames& types,
1266 const AidlStructuredParcelable& defined_type, const Options& options) {
1267 std::string clazz = GetQualifiedName(defined_type);
1268 if (defined_type.IsGeneric()) {
1269 std::vector<std::string> template_params;
1270 for (const auto& parameter : defined_type.GetTypeParameters()) {
1271 template_params.push_back(parameter);
1272 }
1273 clazz += base::StringPrintf("<%s>", base::Join(template_params, ", ").c_str());
1274 }
1275
1276 GenerateSourceIncludes(out, types, defined_type, options);
1277 EnterNdkNamespace(out, defined_type);
1278 out << cpp::TemplateDecl(defined_type);
1279 out << "const char* " << clazz << "::" << kDescriptor << " = \""
1280 << defined_type.GetCanonicalName() << "\";\n";
1281 out << "\n";
1282
1283 GenerateConstantDefinitions(out, defined_type, clazz, cpp::TemplateDecl(defined_type));
1284
1285 {
1286 cpp::ClangDiagnosticIgnoreDeprecated guard(out, cpp::HasDeprecatedField(defined_type));
1287 out << cpp::TemplateDecl(defined_type);
1288 out << "binder_status_t " << clazz << "::readFromParcel(const AParcel* _aidl_parcel) {\n";
1289 out.Indent();
1290 out << "binder_status_t _aidl_ret_status = STATUS_OK;\n";
1291 out << "int32_t _aidl_start_pos = AParcel_getDataPosition(_aidl_parcel);\n";
1292 out << "int32_t _aidl_parcelable_size = 0;\n";
1293 out << "_aidl_ret_status = AParcel_readInt32(_aidl_parcel, &_aidl_parcelable_size);\n";
1294 StatusCheckReturn(out);
1295 out << "if (_aidl_parcelable_size < 4) return STATUS_BAD_VALUE;\n";
1296 out << "if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return STATUS_BAD_VALUE;\n";
1297 for (const auto& variable : defined_type.GetFields()) {
1298 out << "if (AParcel_getDataPosition(_aidl_parcel) - _aidl_start_pos >= "
1299 "_aidl_parcelable_size) "
1300 "{\n"
1301 << " AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size);\n"
1302 << " return _aidl_ret_status;\n"
1303 << "}\n";
1304 out << "_aidl_ret_status = ";
1305 ReadFromParcelFor(
1306 {out, types, variable->GetType(), "_aidl_parcel", "&" + variable->GetName()});
1307 out << ";\n";
1308 StatusCheckReturn(out);
1309 }
1310 out << "AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos + _aidl_parcelable_size);\n"
1311 << "return _aidl_ret_status;\n";
1312 out.Dedent();
1313 out << "}\n";
1314
1315 out << cpp::TemplateDecl(defined_type);
1316 out << "binder_status_t " << clazz << "::writeToParcel(AParcel* _aidl_parcel) const {\n";
1317 out.Indent();
1318 out << "binder_status_t _aidl_ret_status;\n";
1319
1320 out << "size_t _aidl_start_pos = AParcel_getDataPosition(_aidl_parcel);\n";
1321 out << "_aidl_ret_status = AParcel_writeInt32(_aidl_parcel, 0);\n";
1322 StatusCheckReturn(out);
1323
1324 for (const auto& variable : defined_type.GetFields()) {
1325 out << "_aidl_ret_status = ";
1326 WriteToParcelFor({out, types, variable->GetType(), "_aidl_parcel", variable->GetName()});
1327 out << ";\n";
1328 StatusCheckReturn(out);
1329 }
1330 out << "size_t _aidl_end_pos = AParcel_getDataPosition(_aidl_parcel);\n";
1331 out << "AParcel_setDataPosition(_aidl_parcel, _aidl_start_pos);\n";
1332 out << "AParcel_writeInt32(_aidl_parcel, _aidl_end_pos - _aidl_start_pos);\n";
1333 out << "AParcel_setDataPosition(_aidl_parcel, _aidl_end_pos);\n";
1334
1335 out << "return _aidl_ret_status;\n";
1336 out.Dedent();
1337 out << "}\n";
1338 }
1339 out << "\n";
1340 LeaveNdkNamespace(out, defined_type);
1341 }
1342
GenerateParcelClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlUnionDecl & defined_type,const Options & options)1343 void GenerateParcelClassDecl(CodeWriter& out, const AidlTypenames& types,
1344 const AidlUnionDecl& defined_type, const Options& options) {
1345 const std::string clazz = ClassName(defined_type, ClassNames::RAW);
1346
1347 cpp::ClangDiagnosticIgnoreDeprecated guard(out, cpp::HasDeprecatedField(defined_type));
1348 cpp::UnionWriter uw{defined_type, types,
1349 [&](const AidlTypeSpecifier& type, const AidlTypenames& types) {
1350 return NdkNameOf(types, type, StorageMode::STACK);
1351 },
1352 &ConstantValueDecorator};
1353
1354 out << cpp::TemplateDecl(defined_type);
1355 out << "class";
1356 cpp::GenerateDeprecated(out, defined_type);
1357 out << " " << clazz << " {\n";
1358 out << "public:\n";
1359 out.Indent();
1360 if (defined_type.IsFixedSize()) {
1361 out << "typedef std::true_type fixed_size;\n";
1362 } else {
1363 out << "typedef std::false_type fixed_size;\n";
1364 }
1365 out << "static const char* descriptor;\n";
1366 out << "\n";
1367 GenerateNestedTypeDecls(out, types, defined_type, options);
1368 uw.PublicFields(out);
1369
1370 out << "binder_status_t readFromParcel(const AParcel* _parcel);\n";
1371 out << "binder_status_t writeToParcel(AParcel* _parcel) const;\n";
1372 out << "\n";
1373
1374 cpp::GenerateParcelableComparisonOperators(out, defined_type);
1375
1376 out << "static const ::ndk::parcelable_stability_t _aidl_stability = ::ndk::"
1377 << (defined_type.IsVintfStability() ? "STABILITY_VINTF" : "STABILITY_LOCAL") << ";\n";
1378 GenerateConstantDeclarations(out, types, defined_type);
1379 cpp::GenerateToString(out, defined_type);
1380 out.Dedent();
1381 out << "private:\n";
1382 out.Indent();
1383 uw.PrivateFields(out);
1384 out.Dedent();
1385 out << "};\n";
1386 }
1387
GenerateParcelSource(CodeWriter & out,const AidlTypenames & types,const AidlUnionDecl & defined_type,const Options & options)1388 void GenerateParcelSource(CodeWriter& out, const AidlTypenames& types,
1389 const AidlUnionDecl& defined_type, const Options& options) {
1390 std::string clazz = GetQualifiedName(defined_type);
1391 if (defined_type.IsGeneric()) {
1392 std::vector<std::string> template_params;
1393 for (const auto& parameter : defined_type.GetTypeParameters()) {
1394 template_params.push_back(parameter);
1395 }
1396 clazz += base::StringPrintf("<%s>", base::Join(template_params, ", ").c_str());
1397 }
1398
1399 cpp::UnionWriter uw{defined_type, types,
1400 [&](const AidlTypeSpecifier& type, const AidlTypenames& types) {
1401 return NdkNameOf(types, type, StorageMode::STACK);
1402 },
1403 &ConstantValueDecorator};
1404 cpp::ParcelWriterContext ctx{
1405 .status_type = "binder_status_t",
1406 .status_ok = "STATUS_OK",
1407 .status_bad = "STATUS_BAD_VALUE",
1408 .read_func =
1409 [&](CodeWriter& out, const std::string& var, const AidlTypeSpecifier& type) {
1410 ReadFromParcelFor({out, types, type, "_parcel", "&" + var});
1411 },
1412 .write_func =
1413 [&](CodeWriter& out, const std::string& value, const AidlTypeSpecifier& type) {
1414 WriteToParcelFor({out, types, type, "_parcel", value});
1415 },
1416 };
1417
1418 GenerateSourceIncludes(out, types, defined_type, options);
1419 EnterNdkNamespace(out, defined_type);
1420 out << cpp::TemplateDecl(defined_type);
1421 out << "const char* " << clazz << "::" << kDescriptor << " = \""
1422 << defined_type.GetCanonicalName() << "\";\n";
1423 out << "\n";
1424
1425 GenerateConstantDefinitions(out, defined_type, clazz, cpp::TemplateDecl(defined_type));
1426
1427 {
1428 cpp::ClangDiagnosticIgnoreDeprecated guard(out, cpp::HasDeprecatedField(defined_type));
1429 out << cpp::TemplateDecl(defined_type);
1430 out << "binder_status_t " << clazz << "::readFromParcel(const AParcel* _parcel) {\n";
1431 out.Indent();
1432 uw.ReadFromParcel(out, ctx);
1433 out.Dedent();
1434 out << "}\n";
1435
1436 out << cpp::TemplateDecl(defined_type);
1437 out << "binder_status_t " << clazz << "::writeToParcel(AParcel* _parcel) const {\n";
1438 out.Indent();
1439 uw.WriteToParcel(out, ctx);
1440 out.Dedent();
1441 out << "}\n";
1442 }
1443
1444 out << "\n";
1445 LeaveNdkNamespace(out, defined_type);
1446 }
1447
GenerateEnumClassDecl(CodeWriter & out,const AidlTypenames & types,const AidlEnumDeclaration & enum_decl,const Options &)1448 void GenerateEnumClassDecl(CodeWriter& out, const AidlTypenames& types,
1449 const AidlEnumDeclaration& enum_decl, const Options&) {
1450 cpp::GenerateEnumClassDecl(out, enum_decl,
1451 NdkNameOf(types, enum_decl.GetBackingType(), StorageMode::STACK),
1452 ConstantValueDecorator);
1453 out << "\n";
1454 }
1455
1456 } // namespace internals
1457 } // namespace ndk
1458 } // namespace aidl
1459 } // namespace android
1460