1 /**
2 * Copyright (C) 2015, 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_cpp.h"
18 #include "aidl.h"
19
20 #include <algorithm>
21 #include <cctype>
22 #include <cstring>
23 #include <memory>
24 #include <random>
25 #include <set>
26 #include <string>
27
28 #include <android-base/format.h>
29 #include <android-base/stringprintf.h>
30 #include <android-base/strings.h>
31
32 #include "aidl_language.h"
33 #include "aidl_to_common.h"
34 #include "aidl_to_cpp.h"
35
36 #include "aidl_typenames.h"
37 #include "logging.h"
38 #include "os.h"
39
40 using android::base::Join;
41 using android::base::StringPrintf;
42 using std::set;
43 using std::string;
44 using std::unique_ptr;
45 using std::vector;
46
47 namespace android {
48 namespace aidl {
49 namespace cpp {
50 namespace internals {
51 namespace {
52
53 const char kAndroidStatusVarName[] = "_aidl_ret_status";
54 const char kCodeVarName[] = "_aidl_code";
55 const char kFlagsVarName[] = "_aidl_flags";
56 const char kDataVarName[] = "_aidl_data";
57 const char kErrorLabel[] = "_aidl_error";
58 const char kImplVarName[] = "_aidl_impl";
59 const char kDelegateImplVarName[] = "_aidl_delegate";
60 const char kParcelVarName[] = "_aidl_parcel";
61 const char kReplyVarName[] = "_aidl_reply";
62 const char kReturnVarName[] = "_aidl_return";
63 const char kStatusVarName[] = "_aidl_status";
64 const char kTraceVarName[] = "_aidl_trace";
65 const char kAndroidParcelLiteral[] = "::android::Parcel";
66 const char kAndroidStatusLiteral[] = "::android::status_t";
67 const char kAndroidStatusOk[] = "::android::OK";
68 const char kAndroidStatusBadValue[] = "::android::BAD_VALUE";
69 const char kBinderStatusLiteral[] = "::android::binder::Status";
70 const char kIBinderHeader[] = "binder/IBinder.h";
71 const char kIInterfaceHeader[] = "binder/IInterface.h";
72 const char kBinderDelegateHeader[] = "binder/Delegate.h";
73 const char kParcelHeader[] = "binder/Parcel.h";
74 const char kStabilityHeader[] = "binder/Stability.h";
75 const char kStatusHeader[] = "binder/Status.h";
76 const char kString16Header[] = "utils/String16.h";
77 const char kTraceHeader[] = "binder/Trace.h";
78 const char kStrongPointerHeader[] = "utils/StrongPointer.h";
79
GenerateBreakOnStatusNotOk(CodeWriter & out)80 void GenerateBreakOnStatusNotOk(CodeWriter& out) {
81 out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
82 out.Write(" break;\n");
83 out.Write("}\n");
84 }
85
GenerateGotoErrorOnBadStatus(CodeWriter & out)86 void GenerateGotoErrorOnBadStatus(CodeWriter& out) {
87 out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
88 out.Write(" goto %s;\n", kErrorLabel);
89 out.Write("}\n");
90 }
91
92 // Format three types of arg list for method.
93 // for_declaration & !type_name_only: int a // for method decl with type and arg
94 // for_declaration & type_name_only: int /*a*/ // for method decl with type
95 // !for_declaration : a // for method call with arg (with direction)
GenerateArgList(const AidlTypenames & typenames,const AidlMethod & method,bool for_declaration,bool type_name_only)96 string GenerateArgList(const AidlTypenames& typenames, const AidlMethod& method,
97 bool for_declaration, bool type_name_only) {
98 vector<string> method_arguments;
99 for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
100 string literal;
101 // b/144943748: CppNameOf FileDescriptor is unique_fd. Don't pass it by
102 // const reference but by value to make it easier for the user to keep
103 // it beyond the scope of the call. unique_fd is a thin wrapper for an
104 // int (fd) so passing by value is not expensive.
105 const bool non_copyable = IsNonCopyableType(a->GetType(), typenames);
106 if (for_declaration) {
107 // Method declarations need typenames, pointers to out params, and variable
108 // names that match the .aidl specification.
109 literal = CppNameOf(a->GetType(), typenames);
110
111 if (a->IsOut()) {
112 literal = literal + "*";
113 } else {
114 const auto defined_type = typenames.TryGetDefinedType(a->GetType().GetName());
115
116 const bool is_enum = defined_type && defined_type->AsEnumDeclaration() != nullptr;
117 const bool is_primitive = AidlTypenames::IsPrimitiveTypename(a->GetType().GetName());
118
119 // We pass in parameters that are not primitives by const reference.
120 // Arrays of primitives are not primitives.
121 if (!(is_primitive || is_enum || non_copyable) || a->GetType().IsArray()) {
122 literal = "const " + literal + "&";
123 }
124 }
125 if (type_name_only) {
126 literal += " /*" + a->GetName() + "*/";
127 } else {
128 literal += " " + a->GetName();
129 }
130 } else {
131 std::string var_name = BuildVarName(*a);
132 if (a->IsOut()) {
133 literal = "&" + var_name;
134 } else if (non_copyable) {
135 literal = "std::move(" + var_name + ")";
136 } else {
137 literal = var_name;
138 }
139 }
140 method_arguments.push_back(literal);
141 }
142
143 if (method.GetType().GetName() != "void") {
144 string literal;
145 if (for_declaration) {
146 literal = CppNameOf(method.GetType(), typenames) + "*";
147 if (type_name_only) {
148 literal += " /*" + string(kReturnVarName) + "*/";
149 } else {
150 literal += " " + string(kReturnVarName);
151 }
152 } else {
153 literal = string{"&"} + kReturnVarName;
154 }
155 method_arguments.push_back(literal);
156 }
157
158 return Join(method_arguments, ", ");
159 }
160
GenerateMethodDecl(CodeWriter & out,const AidlTypenames & types,const AidlMethod & method,const string & clazz)161 void GenerateMethodDecl(CodeWriter& out, const AidlTypenames& types, const AidlMethod& method,
162 const string& clazz) {
163 string clazz_prefix = clazz.empty() ? "" : clazz + "::";
164 out << "::android::binder::Status " << clazz_prefix << method.GetName() << "("
165 << GenerateArgList(types, method, /*for_declartion=*/true, /*type_name_only=*/false) << ")";
166 }
167
GenerateClientTransaction(CodeWriter & out,const AidlTypenames & typenames,const AidlInterface & interface,const AidlMethod & method,const Options & options)168 void GenerateClientTransaction(CodeWriter& out, const AidlTypenames& typenames,
169 const AidlInterface& interface, const AidlMethod& method,
170 const Options& options) {
171 const string i_name = ClassName(interface, ClassNames::INTERFACE);
172 const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
173 const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
174
175 GenerateMethodDecl(out, typenames, method, bp_name);
176 out << " {\n";
177 out.Indent();
178
179 // Declare parcels to hold our query and the response.
180 out.Write("%s %s;\n", kAndroidParcelLiteral, kDataVarName);
181 if (interface.IsSensitiveData()) {
182 out.Write("%s.markSensitive();\n", kDataVarName);
183 }
184 out.Write("%s.markForBinder(remoteStrong());\n", kDataVarName);
185
186 // Even if we're oneway, the transact method still takes a parcel.
187 out.Write("%s %s;\n", kAndroidParcelLiteral, kReplyVarName);
188
189 // Declare the status_t variable we need for error handling.
190 out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);
191 // We unconditionally return a Status object.
192 out.Write("%s %s;\n", kBinderStatusLiteral, kStatusVarName);
193
194 if (options.GenTraces()) {
195 out.Write(
196 "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppClient\");\n",
197 kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
198 }
199
200 if (options.GenLog()) {
201 out << GenLogBeforeExecute(bp_name, method, false /* isServer */, false /* isNdk */);
202 }
203
204 if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
205 out << "if (true) {\n";
206 out.Write(" %s = ::android::UNKNOWN_TRANSACTION;\n", kAndroidStatusVarName);
207 out << "} else {\n";
208 out.Indent();
209 }
210
211 // Add the name of the interface we're hoping to call.
212 out.Write("%s = %s.writeInterfaceToken(getInterfaceDescriptor());\n", kAndroidStatusVarName,
213 kDataVarName);
214 GenerateGotoErrorOnBadStatus(out);
215
216 for (const auto& a : method.GetArguments()) {
217 const string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
218
219 if (a->IsIn()) {
220 // Serialization looks roughly like:
221 // _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
222 // if (_aidl_ret_status != ::android::OK) { goto error; }
223 out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
224 ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
225 ParcelWriteCastOf(a->GetType(), typenames, var_name).c_str());
226 GenerateGotoErrorOnBadStatus(out);
227 } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
228 // Special case, the length of the out array is written into the parcel.
229 // _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
230 // if (_aidl_ret_status != ::android::OK) { goto error; }
231 out.Write("%s = %s.writeVectorSize(%s);\n", kAndroidStatusVarName, kDataVarName,
232 var_name.c_str());
233 GenerateGotoErrorOnBadStatus(out);
234 }
235 }
236
237 // Invoke the transaction on the remote binder and confirm status.
238 std::vector<std::string> flags;
239 if (method.IsOneway()) flags.push_back("::android::IBinder::FLAG_ONEWAY");
240 if (interface.IsSensitiveData()) flags.push_back("::android::IBinder::FLAG_CLEAR_BUF");
241
242 out.Write("%s = remote()->transact(%s, %s, &%s, %s);\n", kAndroidStatusVarName,
243 GetTransactionIdFor(bn_name, method).c_str(), kDataVarName, kReplyVarName,
244 flags.empty() ? "0" : Join(flags, " | ").c_str());
245
246 // If the method is not implemented in the remote side, try to call the
247 // default implementation, if provided.
248 vector<string> arg_names;
249 for (const auto& a : method.GetArguments()) {
250 if (IsNonCopyableType(a->GetType(), typenames)) {
251 arg_names.emplace_back(StringPrintf("std::move(%s)", a->GetName().c_str()));
252 } else {
253 arg_names.emplace_back(a->GetName());
254 }
255 }
256 if (method.GetType().GetName() != "void") {
257 arg_names.emplace_back(kReturnVarName);
258 }
259 if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
260 out.Dedent();
261 out << "}\n";
262 }
263 out.Write("if (%s == ::android::UNKNOWN_TRANSACTION && %s::getDefaultImpl()) [[unlikely]] {\n",
264 kAndroidStatusVarName, i_name.c_str());
265 out.Write(" return %s::getDefaultImpl()->%s(%s);\n", i_name.c_str(), method.GetName().c_str(),
266 Join(arg_names, ", ").c_str());
267 out.Write("}\n");
268 GenerateGotoErrorOnBadStatus(out);
269
270 if (!method.IsOneway()) {
271 // Strip off the exception header and fail if we see a remote exception.
272 // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
273 // if (_aidl_ret_status != ::android::OK) { goto error; }
274 // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
275 out.Write("%s = %s.readFromParcel(%s);\n", kAndroidStatusVarName, kStatusVarName,
276 kReplyVarName);
277 GenerateGotoErrorOnBadStatus(out);
278 out.Write("if (!%s.isOk()) {\n", kStatusVarName);
279 out.Write(" return %s;\n", kStatusVarName);
280 out.Write("}\n");
281 }
282
283 // Type checking should guarantee that nothing below emits code until "return
284 // status" if we are a oneway method, so no more fear of accessing reply.
285
286 // If the method is expected to return something, read it first by convention.
287 if (method.GetType().GetName() != "void") {
288 out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
289 ParcelReadMethodOf(method.GetType(), typenames).c_str(),
290 ParcelReadCastOf(method.GetType(), typenames, kReturnVarName).c_str());
291 GenerateGotoErrorOnBadStatus(out);
292 }
293
294 for (const AidlArgument* a : method.GetOutArguments()) {
295 // Deserialization looks roughly like:
296 // _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
297 // if (_aidl_status != ::android::OK) { goto _aidl_error; }
298 out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
299 ParcelReadMethodOf(a->GetType(), typenames).c_str(),
300 ParcelReadCastOf(a->GetType(), typenames, a->GetName()).c_str());
301 GenerateGotoErrorOnBadStatus(out);
302 }
303
304 // If we've gotten to here, one of two things is true:
305 // 1) We've read some bad status_t
306 // 2) We've only read status_t == OK and there was no exception in the
307 // response.
308 // In both cases, we're free to set Status from the status_t and return.
309 out.Write("%s:\n", kErrorLabel);
310 out.Write("%s.setFromStatusT(%s);\n", kStatusVarName, kAndroidStatusVarName);
311
312 if (options.GenLog()) {
313 out << GenLogAfterExecute(bp_name, interface, method, kStatusVarName, kReturnVarName,
314 false /* isServer */, false /* isNdk */);
315 }
316
317 out.Write("return %s;\n", kStatusVarName);
318 out.Dedent();
319 out << "}\n";
320 }
321
GenerateClientMetaTransaction(CodeWriter & out,const AidlInterface & interface,const AidlMethod & method,const Options & options)322 void GenerateClientMetaTransaction(CodeWriter& out, const AidlInterface& interface,
323 const AidlMethod& method, const Options& options) {
324 AIDL_FATAL_IF(method.IsUserDefined(), method);
325 const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
326 const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
327 if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
328 // Note: race condition can happen here, but no locking is required
329 // because 1) writing an interger is atomic and 2) this transaction
330 // will always return the same value, i.e., competing threads will
331 // give write the same value to cached_version_.
332 out << "int32_t " << bp_name << "::" << kGetInterfaceVersion << "() {\n"
333 << " if (cached_version_ == -1) {\n"
334 << " ::android::Parcel data;\n"
335 << " ::android::Parcel reply;\n"
336 << " data.writeInterfaceToken(getInterfaceDescriptor());\n"
337 << " ::android::status_t err = remote()->transact("
338 << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
339 << " if (err == ::android::OK) {\n"
340 << " ::android::binder::Status _aidl_status;\n"
341 << " err = _aidl_status.readFromParcel(reply);\n"
342 << " if (err == ::android::OK && _aidl_status.isOk()) {\n"
343 << " cached_version_ = reply.readInt32();\n"
344 << " }\n"
345 << " }\n"
346 << " }\n"
347 << " return cached_version_;\n"
348 << "}\n";
349 out << "\n";
350 }
351 if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
352 out << "std::string " << bp_name << "::" << kGetInterfaceHash << "() {\n"
353 << " std::lock_guard<std::mutex> lockGuard(cached_hash_mutex_);\n"
354 << " if (cached_hash_ == \"-1\") {\n"
355 << " ::android::Parcel data;\n"
356 << " ::android::Parcel reply;\n"
357 << " data.writeInterfaceToken(getInterfaceDescriptor());\n"
358 << " ::android::status_t err = remote()->transact("
359 << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
360 << " if (err == ::android::OK) {\n"
361 << " ::android::binder::Status _aidl_status;\n"
362 << " err = _aidl_status.readFromParcel(reply);\n"
363 << " if (err == ::android::OK && _aidl_status.isOk()) {\n"
364 << " reply.readUtf8FromUtf16(&cached_hash_);\n"
365 << " }\n"
366 << " }\n"
367 << " }\n"
368 << " return cached_hash_;\n"
369 << "}\n";
370 }
371 }
372
373 } // namespace
374
GenerateClientSource(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)375 void GenerateClientSource(CodeWriter& out, const AidlInterface& interface,
376 const AidlTypenames& typenames, const Options& options) {
377 vector<string> include_list = {
378 HeaderFile(interface, ClassNames::CLIENT, false),
379 HeaderFile(interface, ClassNames::SERVER, false), // for TRANSACTION_* consts
380 kParcelHeader};
381 if (options.GenLog()) {
382 include_list.emplace_back("chrono");
383 include_list.emplace_back("functional");
384 }
385 for (const auto& path : include_list) {
386 out << "#include <" << path << ">\n";
387 }
388 out << "\n";
389
390 const string i_name = ClassName(interface, ClassNames::INTERFACE);
391 const string bp_name = ClassName(interface, ClassNames::CLIENT);
392 const string q_name = GetQualifiedName(interface, ClassNames::CLIENT);
393
394 EnterNamespace(out, interface);
395 out << "\n";
396
397 // The constructor just passes the IBinder instance up to the super
398 // class.
399 out << q_name << "::" << bp_name << "(const ::android::sp<::android::IBinder>& _aidl_impl)\n";
400 out << " : BpInterface<" + i_name + ">(_aidl_impl){\n";
401 out << "}\n";
402 out << "\n";
403
404 if (options.GenLog()) {
405 out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
406 << "::logFunc;\n";
407 out << "\n";
408 }
409
410 // Clients define a method per transaction.
411 for (const auto& method : interface.GetMethods()) {
412 if (method->IsUserDefined()) {
413 GenerateClientTransaction(out, typenames, interface, *method, options);
414 } else {
415 GenerateClientMetaTransaction(out, interface, *method, options);
416 }
417 out << "\n";
418 }
419
420 LeaveNamespace(out, interface);
421 }
422
423 namespace {
424
GenerateConstantDefinitions(CodeWriter & out,const AidlDefinedType & type,const AidlTypenames & typenames,const string & template_decl,const string & q_name)425 void GenerateConstantDefinitions(CodeWriter& out, const AidlDefinedType& type,
426 const AidlTypenames& typenames, const string& template_decl,
427 const string& q_name) {
428 for (const auto& constant : type.GetConstantDeclarations()) {
429 const AidlConstantValue& value = constant->GetValue();
430 if (value.GetType() != AidlConstantValue::Type::STRING) continue;
431
432 std::string cpp_type = CppNameOf(constant->GetType(), typenames);
433 out << template_decl;
434 out << "const " << cpp_type << "& " << q_name << "::" << constant->GetName() << "() {\n";
435 out << " static const " << cpp_type << " value("
436 << constant->ValueString(ConstantValueDecorator) << ");\n";
437 out << " return value;\n";
438 out << "}\n";
439 }
440 }
441
GenerateConstantDeclarations(CodeWriter & out,const AidlDefinedType & type,const AidlTypenames & typenames)442 void GenerateConstantDeclarations(CodeWriter& out, const AidlDefinedType& type,
443 const AidlTypenames& typenames) {
444 for (const auto& constant : type.GetConstantDeclarations()) {
445 const AidlTypeSpecifier& type = constant->GetType();
446 const auto cpp_type = CppNameOf(type, typenames);
447 if (type.Signature() == "String") {
448 out << "static const " << cpp_type << "& " << constant->GetName() << "()";
449 GenerateDeprecated(out, *constant);
450 out << ";\n";
451 } else if (type.Signature() == "float" || type.Signature() == "double") {
452 out << "static constexpr " << cpp_type << " " << constant->GetName();
453 GenerateDeprecated(out, *constant);
454 out << " = " << constant->ValueString(ConstantValueDecorator) << ";\n";
455 } else {
456 out << "enum : " << cpp_type << " { " << constant->GetName();
457 GenerateDeprecated(out, *constant);
458 out << " = " << constant->ValueString(ConstantValueDecorator) << " };\n";
459 }
460 }
461 }
462
GenerateServerTransaction(CodeWriter & out,const AidlInterface & interface,const AidlMethod & method,const AidlTypenames & typenames,const Options & options)463 void GenerateServerTransaction(CodeWriter& out, const AidlInterface& interface,
464 const AidlMethod& method, const AidlTypenames& typenames,
465 const Options& options) {
466 const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
467 if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
468 out << "if (true) {\n";
469 out << " _aidl_ret_status = ::android::UNKNOWN_TRANSACTION;\n";
470 out << " break;\n";
471 out << "}\n";
472 }
473
474 // Declare all the parameters now. In the common case, we expect no errors
475 // in serialization.
476 for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
477 out.Write("%s %s;\n", CppNameOf(a->GetType(), typenames).c_str(), BuildVarName(*a).c_str());
478 }
479
480 // Declare a variable to hold the return value.
481 if (method.GetType().GetName() != "void") {
482 out.Write("%s %s;\n", CppNameOf(method.GetType(), typenames).c_str(), kReturnVarName);
483 }
484
485 // Check that the client is calling the correct interface.
486 out.Write("if (!(%s.checkInterface(this))) {\n", kDataVarName);
487 out.Write(" %s = ::android::BAD_TYPE;\n", kAndroidStatusVarName);
488 out.Write(" break;\n");
489 out.Write("}\n");
490
491 if (options.GenTraces()) {
492 out.Write(
493 "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppServer\");\n",
494 kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
495 }
496
497 if (interface.EnforceExpression() || method.GetType().EnforceExpression()) {
498 out.Write("#error Permission checks not implemented for the cpp backend\n");
499 }
500
501 // Deserialize each "in" parameter to the transaction.
502 for (const auto& a: method.GetArguments()) {
503 // Deserialization looks roughly like:
504 // _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
505 // if (_aidl_ret_status != ::android::OK) { break; }
506 const string& var_name = "&" + BuildVarName(*a);
507 if (a->IsIn()) {
508 out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
509 ParcelReadMethodOf(a->GetType(), typenames).c_str(),
510 ParcelReadCastOf(a->GetType(), typenames, var_name).c_str());
511 GenerateBreakOnStatusNotOk(out);
512 } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
513 // Special case, the length of the out array is written into the parcel.
514 // _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
515 // if (_aidl_ret_status != ::android::OK) { break; }
516 out.Write("%s = %s.resizeOutVector(%s);\n", kAndroidStatusVarName, kDataVarName,
517 var_name.c_str());
518 GenerateBreakOnStatusNotOk(out);
519 }
520 }
521
522 if (options.GenLog()) {
523 out << GenLogBeforeExecute(bn_name, method, true /* isServer */, false /* isNdk */);
524 }
525
526 if (!method.GetArguments().empty() && options.GetMinSdkVersion() >= SDK_VERSION_Tiramisu) {
527 out << "if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {\n";
528 out << " _aidl_ret_status = st.writeToParcel(_aidl_reply);\n";
529 out << " break;\n";
530 out << "}\n";
531 }
532
533 // Call the actual method. This is implemented by the subclass.
534 out.Write("%s %s(%s(%s));\n", kBinderStatusLiteral, kStatusVarName, method.GetName().c_str(),
535 GenerateArgList(typenames, method, /*for_declaration=*/false, /*type_name_only=*/false)
536 .c_str());
537
538 if (options.GenLog()) {
539 out << GenLogAfterExecute(bn_name, interface, method, kStatusVarName, kReturnVarName,
540 true /* isServer */, false /* isNdk */);
541 }
542
543 // Write exceptions during transaction handling to parcel.
544 if (!method.IsOneway()) {
545 out.Write("%s = %s.writeToParcel(%s);\n", kAndroidStatusVarName, kStatusVarName, kReplyVarName);
546 GenerateBreakOnStatusNotOk(out);
547 out.Write("if (!%s.isOk()) {\n", kStatusVarName);
548 out.Write(" break;\n");
549 out.Write("}\n");
550 }
551
552 // If we have a return value, write it first.
553 if (method.GetType().GetName() != "void") {
554 out.Write("%s = %s->%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
555 ParcelWriteMethodOf(method.GetType(), typenames).c_str(),
556 ParcelWriteCastOf(method.GetType(), typenames, kReturnVarName).c_str());
557 GenerateBreakOnStatusNotOk(out);
558 }
559 // Write each out parameter to the reply parcel.
560 for (const AidlArgument* a : method.GetOutArguments()) {
561 // Serialization looks roughly like:
562 // _aidl_ret_status = data.WriteInt32(out_param_name);
563 // if (_aidl_ret_status != ::android::OK) { break; }
564 out.Write("%s = %s->%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
565 ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
566 ParcelWriteCastOf(a->GetType(), typenames, BuildVarName(*a)).c_str());
567 GenerateBreakOnStatusNotOk(out);
568 }
569 }
570
GenerateServerMetaTransaction(CodeWriter & out,const AidlInterface & interface,const AidlMethod & method,const Options & options)571 void GenerateServerMetaTransaction(CodeWriter& out, const AidlInterface& interface,
572 const AidlMethod& method, const Options& options) {
573 AIDL_FATAL_IF(method.IsUserDefined(), method);
574
575 string iface = ClassName(interface, ClassNames::INTERFACE);
576 if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
577 out << "_aidl_data.checkInterface(this);\n"
578 << "_aidl_reply->writeNoException();\n";
579 out << "_aidl_reply->writeInt32(" << iface << "::VERSION);\n";
580 }
581 if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
582 out << "_aidl_data.checkInterface(this);\n"
583 << "_aidl_reply->writeNoException();\n";
584 out << "_aidl_reply->writeUtf8AsUtf16(" << iface << "::HASH);\n";
585 }
586 }
587
588 } // namespace
589
GenerateServerOnTransact(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)590 void GenerateServerOnTransact(CodeWriter& out, const AidlInterface& interface,
591 const AidlTypenames& typenames, const Options& options) {
592 const string bn_name = ClassName(interface, ClassNames::SERVER);
593 const string q_name = GetQualifiedName(interface, ClassNames::SERVER);
594
595 bool deprecated = interface.IsDeprecated() ||
596 std::any_of(interface.GetMethods().begin(), interface.GetMethods().end(),
597 [](const auto& m) { return m->IsDeprecated(); });
598 if (deprecated) {
599 out << "#pragma clang diagnostic push\n";
600 out << "#pragma clang diagnostic ignored \"-Wdeprecated\"\n";
601 out << "\n";
602 }
603
604 out.Write("%s %s::onTransact(uint32_t %s, const %s& %s, %s* %s, uint32_t %s) {\n",
605 kAndroidStatusLiteral, q_name.c_str(), kCodeVarName, kAndroidParcelLiteral,
606 kDataVarName, kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
607 out.Indent();
608 // Declare the status_t variable
609 out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);
610
611 // Add the all important switch statement
612 out.Write("switch (%s) {\n", kCodeVarName);
613
614 // The switch statement has a case statement for each transaction code.
615 for (const auto& method : interface.GetMethods()) {
616 out.Write("case %s:\n", GetTransactionIdFor(bn_name, *method).c_str());
617 out << "{\n";
618 out.Indent();
619 if (method->IsUserDefined()) {
620 GenerateServerTransaction(out, interface, *method, typenames, options);
621 } else {
622 GenerateServerMetaTransaction(out, interface, *method, options);
623 }
624 out.Dedent();
625 out << "}\n";
626 out << "break;\n";
627 }
628
629 // The switch statement has a default case which defers to the super class.
630 // The superclass handles a few pre-defined transactions.
631 out << "default:\n";
632 out << "{\n";
633 out.Write(" %s = ::android::BBinder::onTransact(%s, %s, %s, %s);\n", kAndroidStatusVarName,
634 kCodeVarName, kDataVarName, kReplyVarName, kFlagsVarName);
635 out << "}\n";
636 out << "break;\n";
637 out << "}\n"; // switch
638
639 // If we saw a null reference, we can map that to an appropriate exception.
640 out.Write("if (%s == ::android::UNEXPECTED_NULL) {\n", kAndroidStatusVarName);
641 out.Write(" %s = %s::fromExceptionCode(%s::EX_NULL_POINTER).writeOverParcel(%s);\n",
642 kAndroidStatusVarName, kBinderStatusLiteral, kBinderStatusLiteral, kReplyVarName);
643 out.Write("}\n");
644
645 // Finally, the server's onTransact method just returns a status code.
646 out.Write("return %s;\n", kAndroidStatusVarName);
647
648 out.Dedent();
649 out << "}\n";
650 out << "\n";
651
652 if (deprecated) {
653 out << "#pragma clang diagnostic pop\n";
654 out << "\n";
655 }
656 }
657
GenerateServerSource(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)658 void GenerateServerSource(CodeWriter& out, const AidlInterface& interface,
659 const AidlTypenames& typenames, const Options& options) {
660 vector<string> include_list{
661 HeaderFile(interface, ClassNames::SERVER, false),
662 kParcelHeader,
663 kStabilityHeader,
664 };
665 if (options.GenLog()) {
666 include_list.emplace_back("chrono");
667 include_list.emplace_back("functional");
668 }
669 for (const auto& include : include_list) {
670 out << "#include <" << include << ">\n";
671 }
672 out << "\n";
673
674 const string i_name = ClassName(interface, ClassNames::INTERFACE);
675 const string bn_name = ClassName(interface, ClassNames::SERVER);
676 const string q_name = GetQualifiedName(interface, ClassNames::SERVER);
677
678 EnterNamespace(out, interface);
679 out << "\n";
680
681 // constructor
682 out.Write("%s::%s()\n", q_name.c_str(), bn_name.c_str());
683 out << "{\n";
684 out.Indent();
685 if (interface.IsVintfStability()) {
686 out << "::android::internal::Stability::markVintf(this);\n";
687 } else {
688 out << "::android::internal::Stability::markCompilationUnit(this);\n";
689 }
690 out.Dedent();
691 out << "}\n";
692 out << "\n";
693
694 GenerateServerOnTransact(out, interface, typenames, options);
695
696 if (options.Version() > 0) {
697 out << "int32_t " << q_name << "::" << kGetInterfaceVersion << "() {\n"
698 << " return " << i_name << "::VERSION;\n"
699 << "}\n";
700 }
701 if (!options.Hash().empty()) {
702 out << "std::string " << q_name << "::" << kGetInterfaceHash << "() {\n"
703 << " return " << i_name << "::HASH;\n"
704 << "}\n";
705 }
706 if (options.GenLog()) {
707 out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
708 << "::logFunc;\n";
709 }
710
711 LeaveNamespace(out, interface);
712 }
713
GenerateInterfaceSource(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options &)714 void GenerateInterfaceSource(CodeWriter& out, const AidlInterface& interface,
715 const AidlTypenames& typenames, const Options&) {
716 out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
717 out << "#include <" << HeaderFile(interface, ClassNames::CLIENT, false) << ">\n";
718
719 EnterNamespace(out, interface);
720
721 if (auto parent = interface.GetParentType(); parent) {
722 out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE({}, {}, \"{}\")\n",
723 GetQualifiedName(*parent, ClassNames::MAYBE_INTERFACE),
724 ClassName(interface, ClassNames::BASE), interface.GetDescriptor());
725 } else {
726 out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE({}, \"{}\")\n",
727 ClassName(interface, ClassNames::BASE), interface.GetDescriptor());
728 }
729
730 GenerateConstantDefinitions(out, interface, typenames, /*template_decl=*/"",
731 ClassName(interface, ClassNames::INTERFACE));
732
733 LeaveNamespace(out, interface);
734 }
735
GenerateClientClassDecl(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)736 void GenerateClientClassDecl(CodeWriter& out, const AidlInterface& interface,
737 const AidlTypenames& typenames, const Options& options) {
738 const string bp_name = ClassName(interface, ClassNames::CLIENT);
739 const string iface = ClassName(interface, ClassNames::INTERFACE);
740
741 out << "class LIBBINDER_EXPORTED";
742 GenerateDeprecated(out, interface);
743 out << " " << bp_name << " : public ::android::BpInterface<" << iface << "> {\n";
744 out << "public:\n";
745 out.Indent();
746 out << "explicit " << bp_name << "(const ::android::sp<::android::IBinder>& " << kImplVarName
747 << ");\n";
748 out << "virtual ~" << bp_name << "() = default;\n";
749
750 for (const auto& method : interface.GetMethods()) {
751 if (method->IsUserDefined()) {
752 GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
753 out << " override";
754 GenerateDeprecated(out, *method);
755 out << ";\n";
756 } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
757 out << "int32_t " << method->GetName() << "() override;\n";
758 } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
759 out << "std::string " << method->GetName() << "() override;\n";
760 }
761 }
762
763 if (options.GenLog()) {
764 out << kTransactionLogStruct;
765 out << "static std::function<void(const TransactionLog&)> logFunc;\n";
766 }
767 out.Dedent();
768
769 if (options.Version() > 0 || !options.Hash().empty()) {
770 out << "private:\n";
771 out.Indent();
772 if (options.Version() > 0) {
773 out << "int32_t cached_version_ = -1;\n";
774 }
775 if (!options.Hash().empty()) {
776 out << "std::string cached_hash_ = \"-1\";\n";
777 out << "std::mutex cached_hash_mutex_;\n";
778 }
779 out.Dedent();
780 }
781
782 out << "}; // class " << bp_name << "\n";
783 }
784
GenerateClientHeader(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)785 void GenerateClientHeader(CodeWriter& out, const AidlInterface& interface,
786 const AidlTypenames& typenames, const Options& options) {
787 out << "#pragma once\n\n";
788 if (!options.Hash().empty()) {
789 out << "#include <mutex>\n";
790 }
791 out << "#include <" << kIBinderHeader << ">\n";
792 out << "#include <" << kIInterfaceHeader << ">\n";
793 out << "#include <utils/Errors.h>\n";
794 out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
795 if (options.GenLog()) {
796 out << "#include <functional>\n"; // for std::function
797 out << "#include <android/binder_to_string.h>\n";
798 }
799 out << "\n";
800 EnterNamespace(out, interface);
801 GenerateClientClassDecl(out, interface, typenames, options);
802 LeaveNamespace(out, interface);
803 }
804
805 // Some interfaces are declared in .aidl files, but defined elsewhere.
806 // These interfaces can not have Delegators and need to be avoided.
807 // TODO(b/242920522) These should all be defined in .aidl files.
isKnownUndefinedInterface(const std::string & canonicalName)808 bool isKnownUndefinedInterface(const std::string& canonicalName) {
809 static const auto* kKnownUndefinedInterfaces = new std::set<std::string>{
810 "android.hardware.ICamera", "android.hardware.ICameraClient",
811 "android.IOMXNode", "android.IMediaExtractor",
812 "android.IDataSource",
813 };
814 return kKnownUndefinedInterfaces->find(canonicalName) != kKnownUndefinedInterfaces->end();
815 };
816
isDelegateable(const AidlTypeSpecifier & type)817 bool isDelegateable(const AidlTypeSpecifier& type) {
818 return type.GetDefinedType() && type.GetDefinedType()->AsInterface() &&
819 !isKnownUndefinedInterface(type.GetDefinedType()->GetCanonicalName()) && !type.IsArray();
820 }
821
wrapDelegate(CodeWriter & out,const std::string & argName,const AidlTypeSpecifier & type,bool in)822 void wrapDelegate(CodeWriter& out, const std::string& argName, const AidlTypeSpecifier& type,
823 bool in) {
824 const std::string argRef = in ? argName : "*" + argName;
825 const std::string targetArgName = in ? "_" + argName : argName;
826 const std::string targetArgRef = in ? targetArgName : "*" + targetArgName;
827 // input binders need local variables for each arg to pass to the delegate
828 // because the parameters are const
829 if (in) {
830 out << "::android::sp<::" << Join(type.GetSplitName(), "::") << "Delegator> " << targetArgName
831 << ";\n";
832 }
833 out << "if (" << argRef << ") {\n";
834 out.Indent();
835 out << targetArgRef << " = ::android::sp<::" << Join(type.GetSplitName(), "::")
836 << "Delegator>::cast(delegate(" << argRef << "));\n";
837 out.Dedent();
838 out << "}\n";
839 }
840
GenerateServerClassDecl(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)841 void GenerateServerClassDecl(CodeWriter& out, const AidlInterface& interface,
842 const AidlTypenames& typenames, const Options& options) {
843 const string bn_name = ClassName(interface, ClassNames::SERVER);
844 const string iface = ClassName(interface, ClassNames::INTERFACE);
845
846 out << "class LIBBINDER_EXPORTED";
847 GenerateDeprecated(out, interface);
848 out << " " << bn_name << " : public "
849 << "::android::BnInterface<" << iface << "> {\n";
850 out << "public:\n";
851 out.Indent();
852 for (const auto& method : interface.GetMethods()) {
853 out << "static constexpr uint32_t TRANSACTION_" << method->GetName() << " = "
854 << "::android::IBinder::FIRST_CALL_TRANSACTION + " << std::to_string(method->GetId())
855 << ";\n";
856 }
857 out << "explicit " << bn_name << "();\n";
858 out << fmt::format("{} onTransact(uint32_t {}, const {}& {}, {}* {}, uint32_t {}) override;\n",
859 kAndroidStatusLiteral, kCodeVarName, kAndroidParcelLiteral, kDataVarName,
860 kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
861 if (options.Version() > 0) {
862 out << "int32_t " << kGetInterfaceVersion << "();\n";
863 }
864 if (!options.Hash().empty()) {
865 out << "std::string " << kGetInterfaceHash << "();\n";
866 }
867 if (options.GenLog()) {
868 out << kTransactionLogStruct;
869 out << "static std::function<void(const TransactionLog&)> logFunc;\n";
870 }
871 out.Dedent();
872 out << "}; // class " << bn_name << "\n\n";
873
874 std::string d_name = ClassName(interface, ClassNames::DELEGATOR_IMPL);
875 out << "class LIBBINDER_EXPORTED";
876 GenerateDeprecated(out, interface);
877 out << " " << d_name << " : public " << bn_name << " {\n";
878 out << "public:\n";
879 out.Indent();
880 out << "explicit " << d_name << "("
881 << StringPrintf("const ::android::sp<%s> &impl", iface.c_str()) << ") "
882 << StringPrintf(": %s(impl)", kDelegateImplVarName) << " {}\n\n";
883 out << "::android::sp<" << iface << "> getImpl() { return " << kDelegateImplVarName << "; }\n";
884 for (const auto& method : interface.GetMethods()) {
885 if (method->IsUserDefined()) {
886 GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
887 out << " override";
888 GenerateDeprecated(out, *method);
889
890 std::vector<std::string> args;
891
892 // arg name, type
893 std::vector<pair<const std::string, const AidlTypeSpecifier&>> outBinders;
894 std::vector<pair<const std::string, const AidlTypeSpecifier&>> inBinders;
895 for (const auto& arg : method->GetArguments()) {
896 if (isDelegateable(arg->GetType())) {
897 if (arg->IsOut()) {
898 outBinders.push_back({arg->GetName(), arg->GetType()});
899 } else if (arg->IsIn()) {
900 inBinders.push_back({arg->GetName(), arg->GetType()});
901 } else {
902 AIDL_FATAL(*arg) << "inout interface?";
903 }
904 AIDL_FATAL_IF(!arg->IsIn() && !arg->IsOut(), *arg) << "Not in or out?";
905 args.push_back("_" + arg->GetName());
906 } else {
907 if (IsNonCopyableType(arg->GetType(), typenames)) {
908 args.push_back(StringPrintf("std::move(%s)", arg->GetName().c_str()));
909 } else {
910 args.push_back(arg->GetName());
911 }
912 }
913 }
914 if (method->GetType().GetName() != "void") {
915 if (isDelegateable(method->GetType())) {
916 outBinders.push_back({kReturnVarName, method->GetType()});
917 }
918 args.push_back(kReturnVarName);
919 }
920 out << " {\n";
921 out.Indent();
922 for (const auto binder : inBinders) {
923 wrapDelegate(out, binder.first, binder.second, true);
924 }
925 if (outBinders.empty()) {
926 out << "return " << kDelegateImplVarName << "->" << method->GetName() << "("
927 << base::Join(args, ", ") << ");\n";
928 } else {
929 out << "auto _status = " << kDelegateImplVarName << "->" << method->GetName() << "("
930 << base::Join(args, ", ") << ");\n";
931 for (const auto& binder : outBinders) {
932 wrapDelegate(out, binder.first, binder.second, false);
933 }
934 out << "return _status;\n";
935 }
936 out.Dedent();
937 out << "}\n";
938 } else if (method->GetName() == kGetInterfaceVersion && options.Version()) {
939 out << "int32_t " << kGetInterfaceVersion << "()"
940 << " override {\n";
941 out.Indent();
942 out << "int32_t _delegator_ver = " << bn_name << "::" << kGetInterfaceVersion << "();\n";
943 out << "int32_t _impl_ver = " << kDelegateImplVarName << "->" << kGetInterfaceVersion
944 << "();\n";
945 out << "return _delegator_ver < _impl_ver ? _delegator_ver : _impl_ver;\n";
946 out.Dedent();
947 out << "}\n";
948 } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
949 out << "std::string " << kGetInterfaceHash << "()"
950 << " override {\n";
951 out << " return " << kDelegateImplVarName << "->" << kGetInterfaceHash << "();\n";
952 out << "}\n";
953 }
954 }
955 out.Dedent();
956 out << "private:\n";
957 out.Indent();
958 out << "::android::sp<" << iface << "> " << kDelegateImplVarName << ";\n";
959 out.Dedent();
960 out << "}; // class " << d_name << "\n";
961 }
962
963 // Collect all includes for the type's server header. Nested types are visited as well via
964 // VisitTopDown.
GenerateServerHeaderIncludes(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)965 void GenerateServerHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
966 const AidlTypenames& typenames, const Options& options) {
967 struct Visitor : AidlVisitor {
968 const AidlTypenames& typenames;
969 const Options& options;
970 std::set<std::string> includes;
971 Visitor(const AidlTypenames& typenames, const Options& options)
972 : typenames(typenames), options(options) {}
973
974 // Collect includes for each type reference
975 void Visit(const AidlTypeSpecifier& type) override {
976 // Add Bn* header files for types used in this header. The *Delegator
977 // definitions require them.
978 const auto defined_type = type.GetDefinedType();
979 if (defined_type && defined_type->AsInterface()) {
980 if (!isKnownUndefinedInterface(defined_type->GetCanonicalName())) {
981 includes.insert(HeaderFile(*defined_type, ClassNames::SERVER, /*use_os_sep=*/false));
982 }
983 }
984 }
985
986 // Collect implementation-specific includes for each type definition
987 void Visit(const AidlInterface& iface) override {
988 includes.insert(HeaderFile(iface, ClassNames::SERVER, false));
989 }
990 } v(typenames, options);
991 VisitTopDown(v, defined_type);
992
993 v.includes.insert(kBinderDelegateHeader);
994 for (const auto& path : v.includes) {
995 out << "#include <" << path << ">\n";
996 }
997 out << "\n";
998 }
999
GenerateServerHeader(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)1000 void GenerateServerHeader(CodeWriter& out, const AidlInterface& interface,
1001 const AidlTypenames& typenames, const Options& options) {
1002 out << "#pragma once\n\n";
1003 out << "#include <binder/IInterface.h>\n";
1004 out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
1005 if (options.GenLog()) {
1006 out << "#include <functional>\n"; // for std::function
1007 out << "#include <android/binder_to_string.h>\n";
1008 }
1009 GenerateServerHeaderIncludes(out, interface, typenames, options);
1010 out << "\n";
1011 EnterNamespace(out, interface);
1012 GenerateServerClassDecl(out, interface, typenames, options);
1013 LeaveNamespace(out, interface);
1014 }
1015
1016 void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
1017 const AidlTypenames& typenames, const Options& options);
1018
GenerateNestedTypeDecls(CodeWriter & out,const AidlDefinedType & type,const AidlTypenames & typenames,const Options & options)1019 void GenerateNestedTypeDecls(CodeWriter& out, const AidlDefinedType& type,
1020 const AidlTypenames& typenames, const Options& options) {
1021 auto visit = [&](const auto& nested) { GenerateClassDecl(out, nested, typenames, options); };
1022 AIDL_FATAL_IF(!TopologicalVisit(type.GetNestedTypes(), visit), type) << "Cycle detected.";
1023 }
1024
GenerateInterfaceClassDecl(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)1025 void GenerateInterfaceClassDecl(CodeWriter& out, const AidlInterface& interface,
1026 const AidlTypenames& typenames, const Options& options) {
1027 const string i_name = ClassName(interface, ClassNames::INTERFACE);
1028 out << "class LIBBINDER_EXPORTED " << ClassName(interface, ClassNames::DELEGATOR_IMPL) << ";\n\n";
1029 out << "class LIBBINDER_EXPORTED";
1030 GenerateDeprecated(out, interface);
1031 out << " " << i_name << " : public ::android::IInterface {\n";
1032 out << "public:\n";
1033 out.Indent();
1034 out << "typedef " << ClassName(interface, ClassNames::DELEGATOR_IMPL) << " DefaultDelegator;\n";
1035 out << "DECLARE_META_INTERFACE(" << ClassName(interface, ClassNames::BASE) << ")\n";
1036 if (options.Version() > 0) {
1037 if (options.IsLatestUnfrozenVersion()) {
1038 out << "static inline const int32_t VERSION = true ? "
1039 << std::to_string(options.PreviousVersion()) << " : " << std::to_string(options.Version())
1040 << ";\n";
1041 } else {
1042 out << "static inline const int32_t VERSION = " << std::to_string(options.Version()) << ";\n";
1043 }
1044 }
1045 if (!options.Hash().empty()) {
1046 if (options.IsLatestUnfrozenVersion()) {
1047 out << "static inline const std::string HASH = true ? \"" << options.PreviousHash()
1048 << "\" : \"" << options.Hash() << "\";\n";
1049 } else {
1050 out << "static inline const std::string HASH = \"" << options.Hash() << "\";\n";
1051 }
1052 }
1053 GenerateNestedTypeDecls(out, interface, typenames, options);
1054 GenerateConstantDeclarations(out, interface, typenames);
1055 for (const auto& method : interface.GetMethods()) {
1056 if (method->IsUserDefined()) {
1057 out << "virtual ";
1058 GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
1059 GenerateDeprecated(out, *method);
1060 out << " = 0;\n";
1061 } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1062 out << "virtual int32_t " << method->GetName() << "() = 0;\n";
1063 } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1064 out << "virtual std::string " << method->GetName() << "() = 0;\n";
1065 }
1066 }
1067 out.Dedent();
1068 out << "}; // class " << i_name << "\n";
1069 out << "\n";
1070
1071 // Implement the default impl class.
1072 const string default_impl = ClassName(interface, ClassNames::DEFAULT_IMPL);
1073 out << "class LIBBINDER_EXPORTED";
1074 GenerateDeprecated(out, interface);
1075 out << " " << default_impl << " : public " << i_name << " {\n";
1076 out << "public:\n";
1077 out.Indent();
1078 // onAsBinder returns nullptr as this interface is not associated with a
1079 // real binder.
1080 out << "::android::IBinder* onAsBinder() override {\n"
1081 << " return nullptr;\n"
1082 << "}\n";
1083
1084 // Each interface method by default returns UNKNOWN_TRANSACTION with is
1085 // the same status that is returned by transact() when the method is
1086 // not implemented in the server side. In other words, these default
1087 // methods do nothing; they only exist to aid making a real default
1088 // impl class without having to override all methods in an interface.
1089 for (const auto& method : interface.GetMethods()) {
1090 if (method->IsUserDefined()) {
1091 out << "::android::binder::Status " << method->GetName() << "("
1092 << GenerateArgList(typenames, *method, /*for_declaration=*/true, /*type_name_only=*/true)
1093 << ") override";
1094 GenerateDeprecated(out, *method);
1095 out << " {\n"
1096 << " return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
1097 << "}\n";
1098 } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1099 out << "int32_t " << kGetInterfaceVersion << "() override {\n"
1100 << " return 0;\n"
1101 << "}\n";
1102 } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1103 out << "std::string " << kGetInterfaceHash << "() override {\n"
1104 << " return \"\";\n"
1105 << "}\n";
1106 }
1107 }
1108 out.Dedent();
1109 out << "}; // class " << default_impl << "\n";
1110
1111 // When an interface is nested, every class should be defined together here
1112 // because we don't have separate headers for them.
1113 // (e.g. IFoo, IFooDefault, BpFoo, BnFoo, IFooDelegator)
1114 if (interface.GetParentType()) {
1115 GenerateClientClassDecl(out, interface, typenames, options);
1116 GenerateServerClassDecl(out, interface, typenames, options);
1117 }
1118 }
1119
GenerateReadFromParcel(CodeWriter & out,const AidlStructuredParcelable & parcel,const AidlTypenames & typenames)1120 void GenerateReadFromParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
1121 const AidlTypenames& typenames) {
1122 out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
1123 out << "size_t _aidl_start_pos = _aidl_parcel->dataPosition();\n";
1124 out << "int32_t _aidl_parcelable_raw_size = 0;\n";
1125 out << "_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_parcelable_raw_size);\n";
1126 out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1127 out << " return _aidl_ret_status;\n";
1128 out << "}\n";
1129 out << "if (_aidl_parcelable_raw_size < 4) return ::android::BAD_VALUE;\n";
1130 out << "size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n";
1131 out << "if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return ::android::BAD_VALUE;\n";
1132 for (const auto& variable : parcel.GetFields()) {
1133 string method = ParcelReadMethodOf(variable->GetType(), typenames);
1134 string arg = ParcelReadCastOf(variable->GetType(), typenames, "&" + variable->GetName());
1135 out << "if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n";
1136 out << " _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
1137 out << " return _aidl_ret_status;\n";
1138 out << "}\n";
1139 if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
1140 out << "if (false) {\n";
1141 out.Indent();
1142 }
1143 out << "_aidl_ret_status = _aidl_parcel->" << method << "(" << arg << ");\n";
1144 out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1145 out << " return _aidl_ret_status;\n";
1146 out << "}\n";
1147 if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
1148 out.Dedent();
1149 out << "}\n";
1150 }
1151 }
1152 out << "_aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
1153 out << "return _aidl_ret_status;\n";
1154 }
1155
GenerateWriteToParcel(CodeWriter & out,const AidlStructuredParcelable & parcel,const AidlTypenames & typenames)1156 void GenerateWriteToParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
1157 const AidlTypenames& typenames) {
1158 out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
1159 out << "size_t _aidl_start_pos = " << kParcelVarName << "->dataPosition();\n";
1160 out << kParcelVarName << "->writeInt32(0);\n";
1161 for (const auto& variable : parcel.GetFields()) {
1162 string method = ParcelWriteMethodOf(variable->GetType(), typenames);
1163 string arg = ParcelWriteCastOf(variable->GetType(), typenames, variable->GetName());
1164 if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
1165 out << "if (false) {\n";
1166 out.Indent();
1167 }
1168 out << "_aidl_ret_status = " << kParcelVarName << "->" << method << "(" << arg << ");\n";
1169 out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1170 out << " return _aidl_ret_status;\n";
1171 out << "}\n";
1172 if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
1173 out.Dedent();
1174 out << "}\n";
1175 }
1176 }
1177 out << "size_t _aidl_end_pos = " << kParcelVarName << "->dataPosition();\n";
1178 out << kParcelVarName << "->setDataPosition(_aidl_start_pos);\n";
1179 out << kParcelVarName << "->writeInt32(static_cast<int32_t>(_aidl_end_pos - _aidl_start_pos));\n";
1180 out << kParcelVarName << "->setDataPosition(_aidl_end_pos);\n";
1181 out << "return _aidl_ret_status;\n";
1182 }
1183
GetParcelWriterContext(const AidlTypenames & typenames)1184 ParcelWriterContext GetParcelWriterContext(const AidlTypenames& typenames) {
1185 return ParcelWriterContext{
1186 .status_type = kAndroidStatusLiteral,
1187 .status_ok = kAndroidStatusOk,
1188 .status_bad = kAndroidStatusBadValue,
1189 .read_func =
1190 [&](CodeWriter& out, const string& var, const AidlTypeSpecifier& type) {
1191 out << fmt::format("{}->{}({})", kParcelVarName, ParcelReadMethodOf(type, typenames),
1192 ParcelReadCastOf(type, typenames, "&" + var));
1193 },
1194 .write_func =
1195 [&](CodeWriter& out, const string& value, const AidlTypeSpecifier& type) {
1196 out << fmt::format("{}->{}({})", kParcelVarName, ParcelWriteMethodOf(type, typenames),
1197 ParcelWriteCastOf(type, typenames, value));
1198 },
1199 };
1200 }
1201
GenerateReadFromParcel(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1202 void GenerateReadFromParcel(CodeWriter& out, const AidlUnionDecl& decl,
1203 const AidlTypenames& typenames) {
1204 UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1205 uw.ReadFromParcel(out, GetParcelWriterContext(typenames));
1206 }
1207
GenerateWriteToParcel(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1208 void GenerateWriteToParcel(CodeWriter& out, const AidlUnionDecl& decl,
1209 const AidlTypenames& typenames) {
1210 UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1211 uw.WriteToParcel(out, GetParcelWriterContext(typenames));
1212 }
1213
GenerateParcelFields(CodeWriter & out,const AidlStructuredParcelable & decl,const AidlTypenames & typenames)1214 void GenerateParcelFields(CodeWriter& out, const AidlStructuredParcelable& decl,
1215 const AidlTypenames& typenames) {
1216 for (const auto& variable : decl.GetFields()) {
1217 const auto& type = variable->GetType();
1218 std::string cpp_type = CppNameOf(type, typenames);
1219 out << cpp_type;
1220 GenerateDeprecated(out, *variable);
1221 out << " " << variable->GetName();
1222 if (variable->GetDefaultValue()) {
1223 out << " = " << variable->ValueString(ConstantValueDecorator);
1224 } else {
1225 // Some types needs to be explicitly initialized even when no default value is set.
1226 // - ParcelableHolder should be initialized with stability
1227 // - enum should be zero initialized, otherwise the value will be indeterminate
1228 // - fixed-size arrays should be initialized, otherwise the value will be indeterminate
1229 if (type.GetName() == "ParcelableHolder") {
1230 if (decl.IsVintfStability()) {
1231 out << " { ::android::Parcelable::Stability::STABILITY_VINTF }";
1232 } else {
1233 out << " { ::android::Parcelable::Stability::STABILITY_LOCAL }";
1234 }
1235 } else if (typenames.GetEnumDeclaration(type) && !type.IsArray()) {
1236 out << " = " << cpp_type << "(0)";
1237 } else if (type.IsFixedSizeArray() && !type.IsNullable()) {
1238 out << " = {{}}";
1239 }
1240 }
1241 out << ";\n";
1242 }
1243 }
1244
GenerateParcelFields(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1245 void GenerateParcelFields(CodeWriter& out, const AidlUnionDecl& decl,
1246 const AidlTypenames& typenames) {
1247 UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1248 uw.PublicFields(out);
1249 }
1250
1251 template <typename ParcelableType>
GenerateParcelClassDecl(CodeWriter & out,const ParcelableType & parcel,const AidlTypenames & typenames,const Options & options)1252 void GenerateParcelClassDecl(CodeWriter& out, const ParcelableType& parcel,
1253 const AidlTypenames& typenames, const Options& options) {
1254 const string clazz = parcel.GetName();
1255
1256 ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
1257 out << TemplateDecl(parcel);
1258 out << "class LIBBINDER_EXPORTED";
1259 GenerateDeprecated(out, parcel);
1260 out << " " << clazz << " : public ::android::Parcelable {\n";
1261 out << "public:\n";
1262 out.Indent();
1263
1264 GenerateNestedTypeDecls(out, parcel, typenames, options);
1265 GenerateParcelFields(out, parcel, typenames);
1266 GenerateParcelableComparisonOperators(out, parcel);
1267 GenerateConstantDeclarations(out, parcel, typenames);
1268
1269 if (parcel.IsVintfStability()) {
1270 out << "::android::Parcelable::Stability getStability() const override { return "
1271 "::android::Parcelable::Stability::STABILITY_VINTF; }\n";
1272 }
1273
1274 out << kAndroidStatusLiteral << " readFromParcel(const ::android::Parcel* _aidl_parcel) final;\n";
1275 out << kAndroidStatusLiteral << " writeToParcel(::android::Parcel* _aidl_parcel) const final;\n";
1276
1277 const string canonical_name = parcel.GetCanonicalName();
1278 out << "static const ::android::String16& getParcelableDescriptor() {\n"
1279 << " static const ::android::StaticString16 DESCRIPTOR (u\"" << canonical_name << "\");\n"
1280 << " return DESCRIPTOR;\n"
1281 << "}\n";
1282
1283 GenerateToString(out, parcel);
1284
1285 out.Dedent();
1286
1287 if (auto decl = AidlCast<AidlUnionDecl>(parcel); decl) {
1288 out << "private:\n";
1289 out.Indent();
1290 UnionWriter uw{*decl, typenames, &CppNameOf, &ConstantValueDecorator};
1291 uw.PrivateFields(out);
1292 out.Dedent();
1293 }
1294
1295 out << "}; // class " << clazz << "\n";
1296 }
1297
1298 template <typename T>
GenerateParcelSource(CodeWriter & out,const T & parcel,const AidlTypenames & typenames,const Options &)1299 void GenerateParcelSource(CodeWriter& out, const T& parcel, const AidlTypenames& typenames,
1300 const Options&) {
1301 string q_name = GetQualifiedName(parcel);
1302 if (parcel.IsGeneric()) {
1303 q_name += "<" + Join(parcel.GetTypeParameters(), ",") + ">";
1304 }
1305
1306 out << "#include <" << CppHeaderForType(parcel) << ">\n\n";
1307
1308 EnterNamespace(out, parcel);
1309 GenerateConstantDefinitions(out, parcel, typenames, TemplateDecl(parcel), q_name);
1310
1311 {
1312 ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
1313 out << TemplateDecl(parcel);
1314 out << "::android::status_t " << q_name << "::readFromParcel(const ::android::Parcel* "
1315 << kParcelVarName << ") {\n";
1316 out.Indent();
1317 GenerateReadFromParcel(out, parcel, typenames);
1318 out.Dedent();
1319 out << "}\n";
1320
1321 out << TemplateDecl(parcel);
1322 out << "::android::status_t " << q_name << "::writeToParcel(::android::Parcel* "
1323 << kParcelVarName << ") const {\n";
1324 out.Indent();
1325 GenerateWriteToParcel(out, parcel, typenames);
1326 out.Dedent();
1327 out << "}\n";
1328 }
1329 LeaveNamespace(out, parcel);
1330 }
1331
GenerateEnumClassDecl(CodeWriter & out,const AidlEnumDeclaration & enum_decl,const AidlTypenames & typenames)1332 void GenerateEnumClassDecl(CodeWriter& out, const AidlEnumDeclaration& enum_decl,
1333 const AidlTypenames& typenames) {
1334 cpp::GenerateEnumClassDecl(out, enum_decl, CppNameOf(enum_decl.GetBackingType(), typenames),
1335 ConstantValueDecorator);
1336 }
1337
GenerateClassDecl(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1338 void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
1339 const AidlTypenames& typenames, const Options& options) {
1340 if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1341 GenerateInterfaceClassDecl(out, *iface, typenames, options);
1342 } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1343 GenerateParcelClassDecl(out, *parcelable, typenames, options);
1344 } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1345 GenerateParcelClassDecl(out, *union_decl, typenames, options);
1346 } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1347 GenerateEnumClassDecl(out, *enum_decl, typenames);
1348 } else {
1349 AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1350 }
1351 }
1352
1353 } // namespace internals
1354
1355 using namespace internals;
1356
1357 // Collect all includes for the type's header. Nested types are visited as well via VisitTopDown.
GenerateHeaderIncludes(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1358 void GenerateHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
1359 const AidlTypenames& typenames, const Options& options) {
1360 struct Visitor : AidlVisitor {
1361 const AidlTypenames& typenames;
1362 const Options& options;
1363 std::set<std::string> includes;
1364 Visitor(const AidlTypenames& typenames, const Options& options)
1365 : typenames(typenames), options(options) {}
1366
1367 // Collect includes for each type reference including built-in type
1368 void Visit(const AidlTypeSpecifier& type) override {
1369 cpp::AddHeaders(type, typenames, &includes);
1370 }
1371
1372 // Collect implementation-specific includes for each type definition
1373 void Visit(const AidlInterface& iface) override {
1374 includes.insert(kIBinderHeader); // IBinder
1375 includes.insert(kIInterfaceHeader); // IInterface
1376 includes.insert(kStatusHeader); // Status
1377 includes.insert(kStrongPointerHeader); // sp<>
1378
1379 if (options.GenTraces()) {
1380 includes.insert(kTraceHeader);
1381 }
1382
1383 // For a nested interface, client/server classes are declared the same header as well.
1384 if (iface.GetParentType()) {
1385 includes.insert(kBinderDelegateHeader); // Delegate.h
1386 // client/server class provides logFunc when gen_log is on
1387 if (options.GenLog()) {
1388 includes.insert("functional"); // std::function for logFunc
1389 includes.insert("android/binder_to_string.h"); // Generic ToString helper
1390 }
1391 }
1392 }
1393
1394 void Visit(const AidlStructuredParcelable&) override {
1395 AddParcelableCommonHeaders();
1396 includes.insert("tuple"); // std::tie in comparison operators
1397 }
1398
1399 void Visit(const AidlUnionDecl& union_decl) override {
1400 AddParcelableCommonHeaders();
1401 auto union_headers = cpp::UnionWriter::GetHeaders(union_decl);
1402 includes.insert(std::begin(union_headers), std::end(union_headers));
1403 }
1404
1405 void Visit(const AidlEnumDeclaration&) override {
1406 includes.insert("array"); // used in enum_values
1407 includes.insert("binder/Enums.h"); // provides enum_range
1408 includes.insert("string"); // toString() returns std::string
1409 }
1410
1411 void AddParcelableCommonHeaders() {
1412 includes.insert(kParcelHeader); // Parcel in readFromParcel/writeToParcel
1413 includes.insert(kStatusHeader); // Status
1414 includes.insert(kString16Header); // String16 in getParcelableDescriptor
1415 includes.insert("android/binder_to_string.h"); // toString()
1416 }
1417 } v(typenames, options);
1418 VisitTopDown(v, defined_type);
1419
1420 for (const auto& path : v.includes) {
1421 out << "#include <" << path << ">\n";
1422 }
1423 out << "\n";
1424 if (v.includes.count("cassert")) {
1425 // TODO(b/31559095) bionic on host should define __assert2
1426 out << "#ifndef __BIONIC__\n#define __assert2(a,b,c,d) ((void)0)\n#endif\n\n";
1427 }
1428 }
1429
1430 // Generic parcelables and enum utilities should be defined in header.
GenerateHeaderDefinitions(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1431 void GenerateHeaderDefinitions(CodeWriter& out, const AidlDefinedType& defined_type,
1432 const AidlTypenames& typenames, const Options& options) {
1433 struct Visitor : AidlVisitor {
1434 CodeWriter& out;
1435 const AidlTypenames& typenames;
1436 const Options& options;
1437 Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
1438 : out(out), typenames(typenames), options(options) {}
1439
1440 void Visit(const AidlEnumDeclaration& enum_decl) override {
1441 const auto backing_type = CppNameOf(enum_decl.GetBackingType(), typenames);
1442 EnterNamespace(out, enum_decl);
1443 out << GenerateEnumToString(enum_decl, backing_type);
1444 LeaveNamespace(out, enum_decl);
1445
1446 out << "namespace android {\n";
1447 out << "namespace internal {\n";
1448 out << GenerateEnumValues(enum_decl, {""});
1449 out << "} // namespace internal\n";
1450 out << "} // namespace android\n";
1451 }
1452
1453 void Visit(const AidlStructuredParcelable& parcelable) override {
1454 if (parcelable.IsGeneric()) {
1455 GenerateParcelSource(out, parcelable, typenames, options);
1456 }
1457 }
1458
1459 void Visit(const AidlUnionDecl& union_decl) override {
1460 if (union_decl.IsGeneric()) {
1461 GenerateParcelSource(out, union_decl, typenames, options);
1462 }
1463 }
1464
1465 } v(out, typenames, options);
1466 VisitTopDown(v, defined_type);
1467 }
1468
GenerateHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1469 void GenerateHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1470 const AidlTypenames& typenames, const Options& options) {
1471 if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1472 out << "#error TODO(b/111362593) parcelables do not have headers";
1473 return;
1474 }
1475 out << "#pragma once\n\n";
1476 GenerateHeaderIncludes(out, defined_type, typenames, options);
1477 GenerateForwardDecls(out, defined_type, false);
1478 EnterNamespace(out, defined_type);
1479 // Each class decl contains its own nested types' class decls
1480 GenerateClassDecl(out, defined_type, typenames, options);
1481 LeaveNamespace(out, defined_type);
1482 GenerateHeaderDefinitions(out, defined_type, typenames, options);
1483 }
1484
GenerateClientHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1485 void GenerateClientHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1486 const AidlTypenames& typenames, const Options& options) {
1487 if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1488 GenerateClientHeader(out, *iface, typenames, options);
1489 } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1490 out << "#error TODO(b/111362593) parcelables do not have bp classes";
1491 } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1492 out << "#error TODO(b/111362593) parcelables do not have bp classes";
1493 } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1494 out << "#error TODO(b/111362593) enums do not have bp classes";
1495 } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1496 out << "#error TODO(b/111362593) parcelables do not have bp classes";
1497 } else {
1498 AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1499 }
1500 }
1501
GenerateServerHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1502 void GenerateServerHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1503 const AidlTypenames& typenames, const Options& options) {
1504 if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1505 GenerateServerHeader(out, *iface, typenames, options);
1506 } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1507 out << "#error TODO(b/111362593) parcelables do not have bn classes";
1508 } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1509 out << "#error TODO(b/111362593) parcelables do not have bn classes";
1510 } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1511 out << "#error TODO(b/111362593) enums do not have bn classes";
1512 } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1513 out << "#error TODO(b/111362593) parcelables do not have bn classes";
1514 } else {
1515 AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1516 }
1517 }
1518
GenerateSource(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1519 void GenerateSource(CodeWriter& out, const AidlDefinedType& defined_type,
1520 const AidlTypenames& typenames, const Options& options) {
1521 struct Visitor : AidlVisitor {
1522 CodeWriter& out;
1523 const AidlTypenames& typenames;
1524 const Options& options;
1525 Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
1526 : out(out), typenames(typenames), options(options) {}
1527
1528 void Visit(const AidlInterface& interface) override {
1529 GenerateInterfaceSource(out, interface, typenames, options);
1530 GenerateClientSource(out, interface, typenames, options);
1531 GenerateServerSource(out, interface, typenames, options);
1532 }
1533
1534 void Visit(const AidlStructuredParcelable& parcelable) override {
1535 if (!parcelable.IsGeneric()) {
1536 GenerateParcelSource(out, parcelable, typenames, options);
1537 } else {
1538 out << "\n";
1539 }
1540 }
1541
1542 void Visit(const AidlUnionDecl& union_decl) override {
1543 if (!union_decl.IsGeneric()) {
1544 GenerateParcelSource(out, union_decl, typenames, options);
1545 } else {
1546 out << "\n";
1547 }
1548 }
1549
1550 void Visit(const AidlEnumDeclaration& enum_decl) override {
1551 if (!enum_decl.GetParentType()) {
1552 out << "// This file is intentionally left blank as placeholder for enum declaration.\n";
1553 }
1554 }
1555
1556 void Visit(const AidlParcelable& parcelable) override {
1557 AIDL_FATAL_IF(parcelable.GetParentType(), parcelable)
1558 << "Unstructured parcelable can't be nested.";
1559 out << "// This file is intentionally left blank as placeholder for parcel declaration.\n";
1560 }
1561 } v(out, typenames, options);
1562 VisitTopDown(v, defined_type);
1563 }
1564
GenerateCpp(const string & output_file,const Options & options,const AidlTypenames & typenames,const AidlDefinedType & defined_type,const IoDelegate & io_delegate)1565 bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
1566 const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
1567 if (!ValidateOutputFilePath(output_file, options, defined_type)) {
1568 return false;
1569 }
1570
1571 using GenFn = void (*)(CodeWriter& out, const AidlDefinedType& defined_type,
1572 const AidlTypenames& typenames, const Options& options);
1573 // Wrap Generate* function to handle CodeWriter for a file.
1574 auto gen = [&](auto file, GenFn fn) {
1575 unique_ptr<CodeWriter> writer(io_delegate.GetCodeWriter(file));
1576
1577 GenerateAutoGenHeader(*writer, options);
1578
1579 fn(*writer, defined_type, typenames, options);
1580 AIDL_FATAL_IF(!writer->Close(), defined_type) << "I/O Error!";
1581 return true;
1582 };
1583
1584 return gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::RAW),
1585 &GenerateHeader) &&
1586 gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::CLIENT),
1587 &GenerateClientHeader) &&
1588 gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::SERVER),
1589 &GenerateServerHeader) &&
1590 gen(output_file, &GenerateSource);
1591 }
1592
1593 } // namespace cpp
1594 } // namespace aidl
1595 } // namespace android
1596