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