generate_cpp.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  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. #include "generate_cpp.h"
  17. #include "aidl.h"
  18. #include <cctype>
  19. #include <cstring>
  20. #include <memory>
  21. #include <random>
  22. #include <set>
  23. #include <string>
  24. #include <android-base/stringprintf.h>
  25. #include "aidl_language.h"
  26. #include "aidl_to_cpp.h"
  27. #include "ast_cpp.h"
  28. #include "code_writer.h"
  29. #include "logging.h"
  30. #include "os.h"
  31. using android::base::Join;
  32. using android::base::StringPrintf;
  33. using std::set;
  34. using std::string;
  35. using std::unique_ptr;
  36. using std::vector;
  37. namespace android {
  38. namespace aidl {
  39. namespace cpp {
  40. namespace internals {
  41. namespace {
  42. const char kAndroidStatusVarName[] = "_aidl_ret_status";
  43. const char kCodeVarName[] = "_aidl_code";
  44. const char kFlagsVarName[] = "_aidl_flags";
  45. const char kDataVarName[] = "_aidl_data";
  46. const char kErrorLabel[] = "_aidl_error";
  47. const char kImplVarName[] = "_aidl_impl";
  48. const char kReplyVarName[] = "_aidl_reply";
  49. const char kReturnVarName[] = "_aidl_return";
  50. const char kStatusVarName[] = "_aidl_status";
  51. const char kTraceVarName[] = "_aidl_trace";
  52. const char kAndroidParcelLiteral[] = "::android::Parcel";
  53. const char kAndroidStatusLiteral[] = "::android::status_t";
  54. const char kAndroidStatusOk[] = "::android::OK";
  55. const char kBinderStatusLiteral[] = "::android::binder::Status";
  56. const char kIBinderHeader[] = "binder/IBinder.h";
  57. const char kIInterfaceHeader[] = "binder/IInterface.h";
  58. const char kParcelHeader[] = "binder/Parcel.h";
  59. const char kStatusHeader[] = "binder/Status.h";
  60. const char kString16Header[] = "utils/String16.h";
  61. const char kTraceHeader[] = "utils/Trace.h";
  62. const char kStrongPointerHeader[] = "utils/StrongPointer.h";
  63. const char kAndroidBaseMacrosHeader[] = "android-base/macros.h";
  64. unique_ptr<AstNode> BreakOnStatusNotOk() {
  65. IfStatement* ret = new IfStatement(new Comparison(
  66. new LiteralExpression(kAndroidStatusVarName), "!=",
  67. new LiteralExpression(kAndroidStatusOk)));
  68. ret->OnTrue()->AddLiteral("break");
  69. return unique_ptr<AstNode>(ret);
  70. }
  71. unique_ptr<AstNode> GotoErrorOnBadStatus() {
  72. IfStatement* ret = new IfStatement(new Comparison(
  73. new LiteralExpression(kAndroidStatusVarName), "!=",
  74. new LiteralExpression(kAndroidStatusOk)));
  75. ret->OnTrue()->AddLiteral(StringPrintf("goto %s", kErrorLabel));
  76. return unique_ptr<AstNode>(ret);
  77. }
  78. unique_ptr<AstNode> ReturnOnStatusNotOk() {
  79. IfStatement* ret = new IfStatement(new Comparison(new LiteralExpression(kAndroidStatusVarName),
  80. "!=", new LiteralExpression(kAndroidStatusOk)));
  81. ret->OnTrue()->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName));
  82. return unique_ptr<AstNode>(ret);
  83. }
  84. ArgList BuildArgList(const TypeNamespace& types, const AidlMethod& method, bool for_declaration,
  85. bool type_name_only = false) {
  86. // Build up the argument list for the server method call.
  87. vector<string> method_arguments;
  88. for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
  89. string literal;
  90. if (for_declaration) {
  91. // Method declarations need types, pointers to out params, and variable
  92. // names that match the .aidl specification.
  93. const Type* type = a->GetType().GetLanguageType<Type>();
  94. literal = type->CppType();
  95. if (a->IsOut()) {
  96. literal = literal + "*";
  97. } else {
  98. // We pass in parameters that are not primitives by const reference.
  99. // Arrays of primitives are not primitives.
  100. if (!type->IsCppPrimitive() || a->GetType().IsArray()) {
  101. literal = "const " + literal + "&";
  102. }
  103. }
  104. if (!type_name_only) {
  105. literal += " " + a->GetName();
  106. }
  107. } else {
  108. if (a->IsOut()) { literal = "&"; }
  109. literal += BuildVarName(*a);
  110. }
  111. method_arguments.push_back(literal);
  112. }
  113. const Type* return_type = method.GetType().GetLanguageType<Type>();
  114. if (return_type != types.VoidType()) {
  115. string literal;
  116. if (for_declaration) {
  117. literal = StringPrintf("%s* %s", return_type->CppType().c_str(),
  118. type_name_only ? "" : kReturnVarName);
  119. } else {
  120. literal = string{"&"} + kReturnVarName;
  121. }
  122. method_arguments.push_back(literal);
  123. }
  124. return ArgList(method_arguments);
  125. }
  126. unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
  127. const TypeNamespace& types,
  128. bool for_interface) {
  129. uint32_t modifiers = 0;
  130. if (for_interface) {
  131. modifiers |= MethodDecl::IS_VIRTUAL;
  132. modifiers |= MethodDecl::IS_PURE_VIRTUAL;
  133. } else {
  134. modifiers |= MethodDecl::IS_OVERRIDE;
  135. }
  136. return unique_ptr<Declaration>{
  137. new MethodDecl{kBinderStatusLiteral,
  138. method.GetName(),
  139. BuildArgList(types, method, true /* for method decl */),
  140. modifiers}};
  141. }
  142. unique_ptr<Declaration> BuildMetaMethodDecl(const AidlMethod& method, const TypeNamespace&,
  143. const Options& options, bool for_interface) {
  144. CHECK(!method.IsUserDefined());
  145. if (method.GetName() == kGetInterfaceVersion && options.Version()) {
  146. std::ostringstream code;
  147. if (for_interface) {
  148. code << "virtual ";
  149. }
  150. code << "int32_t " << kGetInterfaceVersion << "()";
  151. if (for_interface) {
  152. code << " = 0;\n";
  153. } else {
  154. code << " override;\n";
  155. }
  156. return unique_ptr<Declaration>(new LiteralDecl(code.str()));
  157. }
  158. return nullptr;
  159. }
  160. std::vector<unique_ptr<Declaration>> NestInNamespaces(vector<unique_ptr<Declaration>> decls,
  161. const vector<string>& package) {
  162. auto it = package.crbegin(); // Iterate over the namespaces inner to outer
  163. for (; it != package.crend(); ++it) {
  164. vector<unique_ptr<Declaration>> inner;
  165. inner.emplace_back(unique_ptr<Declaration>{new CppNamespace{*it, std::move(decls)}});
  166. decls = std::move(inner);
  167. }
  168. return decls;
  169. }
  170. std::vector<unique_ptr<Declaration>> NestInNamespaces(unique_ptr<Declaration> decl,
  171. const vector<string>& package) {
  172. vector<unique_ptr<Declaration>> decls;
  173. decls.push_back(std::move(decl));
  174. return NestInNamespaces(std::move(decls), package);
  175. }
  176. bool DeclareLocalVariable(const AidlArgument& a, StatementBlock* b) {
  177. const Type* cpp_type = a.GetType().GetLanguageType<Type>();
  178. if (!cpp_type) { return false; }
  179. string type = cpp_type->CppType();
  180. b->AddLiteral(type + " " + BuildVarName(a));
  181. return true;
  182. }
  183. string BuildHeaderGuard(const AidlDefinedType& defined_type, ClassNames header_type) {
  184. string class_name = ClassName(defined_type, header_type);
  185. for (size_t i = 1; i < class_name.size(); ++i) {
  186. if (isupper(class_name[i])) {
  187. class_name.insert(i, "_");
  188. ++i;
  189. }
  190. }
  191. string ret = StringPrintf("AIDL_GENERATED_%s_%s_H_", defined_type.GetPackage().c_str(),
  192. class_name.c_str());
  193. for (char& c : ret) {
  194. if (c == '.') {
  195. c = '_';
  196. }
  197. c = toupper(c);
  198. }
  199. return ret;
  200. }
  201. unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types,
  202. const AidlInterface& interface,
  203. const AidlMethod& method, const Options& options) {
  204. const string i_name = ClassName(interface, ClassNames::INTERFACE);
  205. const string bp_name = ClassName(interface, ClassNames::CLIENT);
  206. unique_ptr<MethodImpl> ret{new MethodImpl{
  207. kBinderStatusLiteral, bp_name, method.GetName(),
  208. ArgList{BuildArgList(types, method, true /* for method decl */)}}};
  209. StatementBlock* b = ret->GetStatementBlock();
  210. // Declare parcels to hold our query and the response.
  211. b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kDataVarName));
  212. // Even if we're oneway, the transact method still takes a parcel.
  213. b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kReplyVarName));
  214. // Declare the status_t variable we need for error handling.
  215. b->AddLiteral(StringPrintf("%s %s = %s", kAndroidStatusLiteral,
  216. kAndroidStatusVarName,
  217. kAndroidStatusOk));
  218. // We unconditionally return a Status object.
  219. b->AddLiteral(StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName));
  220. if (options.GenTraces()) {
  221. b->AddLiteral(
  222. StringPrintf("ScopedTrace %s(ATRACE_TAG_AIDL, \"%s::%s::cppClient\")",
  223. kTraceVarName, interface.GetName().c_str(), method.GetName().c_str()));
  224. }
  225. if (options.GenLog()) {
  226. b->AddLiteral(GenLogBeforeExecute(bp_name, method, false /* isServer */, false /* isNdk */),
  227. false /* no semicolon */);
  228. }
  229. // Add the name of the interface we're hoping to call.
  230. b->AddStatement(new Assignment(
  231. kAndroidStatusVarName,
  232. new MethodCall(StringPrintf("%s.writeInterfaceToken",
  233. kDataVarName),
  234. "getInterfaceDescriptor()")));
  235. b->AddStatement(GotoErrorOnBadStatus());
  236. for (const auto& a: method.GetArguments()) {
  237. const Type* type = a->GetType().GetLanguageType<Type>();
  238. string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
  239. var_name = type->WriteCast(var_name);
  240. if (a->IsIn()) {
  241. // Serialization looks roughly like:
  242. // _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
  243. // if (_aidl_ret_status != ::android::OK) { goto error; }
  244. const string& method = type->WriteToParcelMethod();
  245. b->AddStatement(new Assignment(
  246. kAndroidStatusVarName,
  247. new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
  248. ArgList(var_name))));
  249. b->AddStatement(GotoErrorOnBadStatus());
  250. } else if (a->IsOut() && a->GetType().IsArray()) {
  251. // Special case, the length of the out array is written into the parcel.
  252. // _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
  253. // if (_aidl_ret_status != ::android::OK) { goto error; }
  254. b->AddStatement(new Assignment(
  255. kAndroidStatusVarName,
  256. new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName),
  257. ArgList(var_name))));
  258. b->AddStatement(GotoErrorOnBadStatus());
  259. }
  260. }
  261. // Invoke the transaction on the remote binder and confirm status.
  262. string transaction_code = GetTransactionIdFor(method);
  263. vector<string> args = {transaction_code, kDataVarName,
  264. StringPrintf("&%s", kReplyVarName)};
  265. if (method.IsOneway()) {
  266. args.push_back("::android::IBinder::FLAG_ONEWAY");
  267. }
  268. b->AddStatement(new Assignment(
  269. kAndroidStatusVarName,
  270. new MethodCall("remote()->transact",
  271. ArgList(args))));
  272. // If the method is not implemented in the remote side, try to call the
  273. // default implementation, if provided.
  274. vector<string> arg_names;
  275. for (const auto& a : method.GetArguments()) {
  276. arg_names.emplace_back(a->GetName());
  277. }
  278. if (method.GetType().GetLanguageType<Type>() != types.VoidType()) {
  279. arg_names.emplace_back(kReturnVarName);
  280. }
  281. b->AddLiteral(StringPrintf("if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && "
  282. "%s::getDefaultImpl())) {\n"
  283. " return %s::getDefaultImpl()->%s(%s);\n"
  284. "}\n",
  285. i_name.c_str(), i_name.c_str(), method.GetName().c_str(),
  286. Join(arg_names, ", ").c_str()),
  287. false /* no semicolon */);
  288. b->AddStatement(GotoErrorOnBadStatus());
  289. if (!method.IsOneway()) {
  290. // Strip off the exception header and fail if we see a remote exception.
  291. // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
  292. // if (_aidl_ret_status != ::android::OK) { goto error; }
  293. // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
  294. b->AddStatement(new Assignment(
  295. kAndroidStatusVarName,
  296. StringPrintf("%s.readFromParcel(%s)", kStatusVarName, kReplyVarName)));
  297. b->AddStatement(GotoErrorOnBadStatus());
  298. IfStatement* exception_check = new IfStatement(
  299. new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
  300. b->AddStatement(exception_check);
  301. exception_check->OnTrue()->AddLiteral(
  302. StringPrintf("return %s", kStatusVarName));
  303. }
  304. // Type checking should guarantee that nothing below emits code until "return
  305. // status" if we are a oneway method, so no more fear of accessing reply.
  306. // If the method is expected to return something, read it first by convention.
  307. const Type* return_type = method.GetType().GetLanguageType<Type>();
  308. if (return_type != types.VoidType()) {
  309. const string& method_call = return_type->ReadFromParcelMethod();
  310. b->AddStatement(new Assignment(
  311. kAndroidStatusVarName,
  312. new MethodCall(StringPrintf("%s.%s", kReplyVarName,
  313. method_call.c_str()),
  314. ArgList(kReturnVarName))));
  315. b->AddStatement(GotoErrorOnBadStatus());
  316. }
  317. for (const AidlArgument* a : method.GetOutArguments()) {
  318. // Deserialization looks roughly like:
  319. // _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
  320. // if (_aidl_status != ::android::OK) { goto _aidl_error; }
  321. string method =
  322. a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
  323. b->AddStatement(new Assignment(
  324. kAndroidStatusVarName,
  325. new MethodCall(StringPrintf("%s.%s", kReplyVarName,
  326. method.c_str()),
  327. ArgList(a->GetName()))));
  328. b->AddStatement(GotoErrorOnBadStatus());
  329. }
  330. // If we've gotten to here, one of two things is true:
  331. // 1) We've read some bad status_t
  332. // 2) We've only read status_t == OK and there was no exception in the
  333. // response.
  334. // In both cases, we're free to set Status from the status_t and return.
  335. b->AddLiteral(StringPrintf("%s:\n", kErrorLabel), false /* no semicolon */);
  336. b->AddLiteral(
  337. StringPrintf("%s.setFromStatusT(%s)", kStatusVarName,
  338. kAndroidStatusVarName));
  339. if (options.GenLog()) {
  340. b->AddLiteral(GenLogAfterExecute(bp_name, interface, method, kStatusVarName, kReturnVarName,
  341. false /* isServer */, false /* isNdk */),
  342. false /* no semicolon */);
  343. }
  344. b->AddLiteral(StringPrintf("return %s", kStatusVarName));
  345. return unique_ptr<Declaration>(ret.release());
  346. }
  347. unique_ptr<Declaration> DefineClientMetaTransaction(const TypeNamespace&,
  348. const AidlInterface& interface,
  349. const AidlMethod& method,
  350. const Options& options) {
  351. CHECK(!method.IsUserDefined());
  352. if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
  353. const string iface = ClassName(interface, ClassNames::INTERFACE);
  354. const string proxy = ClassName(interface, ClassNames::CLIENT);
  355. // Note: race condition can happen here, but no locking is required
  356. // because 1) writing an interger is atomic and 2) this transaction
  357. // will always return the same value, i.e., competing threads will
  358. // give write the same value to cached_version_.
  359. std::ostringstream code;
  360. code << "int32_t " << proxy << "::" << kGetInterfaceVersion << "() {\n"
  361. << " if (cached_version_ == -1) {\n"
  362. << " ::android::Parcel data;\n"
  363. << " ::android::Parcel reply;\n"
  364. << " data.writeInterfaceToken(getInterfaceDescriptor());\n"
  365. << " ::android::status_t err = remote()->transact(" << GetTransactionIdFor(method)
  366. << ", data, &reply);\n"
  367. << " if (err == ::android::OK) {\n"
  368. << " ::android::binder::Status _aidl_status;\n"
  369. << " err = _aidl_status.readFromParcel(reply);\n"
  370. << " if (err == ::android::OK && _aidl_status.isOk()) {\n"
  371. << " cached_version_ = reply.readInt32();\n"
  372. << " }\n"
  373. << " }\n"
  374. << " }\n"
  375. << " return cached_version_;\n"
  376. << "}\n";
  377. return unique_ptr<Declaration>(new LiteralDecl(code.str()));
  378. }
  379. return nullptr;
  380. }
  381. } // namespace
  382. unique_ptr<Document> BuildClientSource(const TypeNamespace& types, const AidlInterface& interface,
  383. const Options& options) {
  384. vector<string> include_list = {
  385. HeaderFile(interface, ClassNames::CLIENT, false),
  386. kParcelHeader,
  387. kAndroidBaseMacrosHeader
  388. };
  389. if (options.GenLog()) {
  390. include_list.emplace_back("chrono");
  391. include_list.emplace_back("functional");
  392. include_list.emplace_back("json/value.h");
  393. }
  394. vector<unique_ptr<Declaration>> file_decls;
  395. // The constructor just passes the IBinder instance up to the super
  396. // class.
  397. const string i_name = ClassName(interface, ClassNames::INTERFACE);
  398. file_decls.push_back(unique_ptr<Declaration>{new ConstructorImpl{
  399. ClassName(interface, ClassNames::CLIENT),
  400. ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
  401. kImplVarName)},
  402. { "BpInterface<" + i_name + ">(" + kImplVarName + ")" }}});
  403. if (options.GenLog()) {
  404. string code;
  405. ClassName(interface, ClassNames::CLIENT);
  406. CodeWriterPtr writer = CodeWriter::ForString(&code);
  407. (*writer) << "std::function<void(const Json::Value&)> "
  408. << ClassName(interface, ClassNames::CLIENT) << "::logFunc;\n";
  409. writer->Close();
  410. file_decls.push_back(unique_ptr<Declaration>(new LiteralDecl(code)));
  411. }
  412. // Clients define a method per transaction.
  413. for (const auto& method : interface.GetMethods()) {
  414. unique_ptr<Declaration> m;
  415. if (method->IsUserDefined()) {
  416. m = DefineClientTransaction(types, interface, *method, options);
  417. } else {
  418. m = DefineClientMetaTransaction(types, interface, *method, options);
  419. }
  420. if (!m) { return nullptr; }
  421. file_decls.push_back(std::move(m));
  422. }
  423. return unique_ptr<Document>{new CppSource{
  424. include_list,
  425. NestInNamespaces(std::move(file_decls), interface.GetSplitPackage())}};
  426. }
  427. namespace {
  428. bool HandleServerTransaction(const TypeNamespace& types, const AidlInterface& interface,
  429. const AidlMethod& method, const Options& options, StatementBlock* b) {
  430. // Declare all the parameters now. In the common case, we expect no errors
  431. // in serialization.
  432. for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
  433. if (!DeclareLocalVariable(*a, b)) {
  434. return false;
  435. }
  436. }
  437. // Declare a variable to hold the return value.
  438. const Type* return_type = method.GetType().GetLanguageType<Type>();
  439. if (return_type != types.VoidType()) {
  440. b->AddLiteral(StringPrintf(
  441. "%s %s", return_type->CppType().c_str(),
  442. kReturnVarName));
  443. }
  444. // Check that the client is calling the correct interface.
  445. IfStatement* interface_check = new IfStatement(
  446. new MethodCall(StringPrintf("%s.checkInterface",
  447. kDataVarName), "this"),
  448. true /* invert the check */);
  449. b->AddStatement(interface_check);
  450. interface_check->OnTrue()->AddStatement(
  451. new Assignment(kAndroidStatusVarName, "::android::BAD_TYPE"));
  452. interface_check->OnTrue()->AddLiteral("break");
  453. // Deserialize each "in" parameter to the transaction.
  454. for (const auto& a: method.GetArguments()) {
  455. // Deserialization looks roughly like:
  456. // _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
  457. // if (_aidl_ret_status != ::android::OK) { break; }
  458. const Type* type = a->GetType().GetLanguageType<Type>();
  459. const string& readMethod = type->ReadFromParcelMethod();
  460. if (a->IsIn()) {
  461. b->AddStatement(new Assignment{
  462. kAndroidStatusVarName,
  463. new MethodCall{string(kDataVarName) + "." + readMethod,
  464. "&" + BuildVarName(*a)}});
  465. b->AddStatement(BreakOnStatusNotOk());
  466. } else if (a->IsOut() && a->GetType().IsArray()) {
  467. // Special case, the length of the out array is written into the parcel.
  468. // _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
  469. // if (_aidl_ret_status != ::android::OK) { break; }
  470. b->AddStatement(new Assignment{
  471. kAndroidStatusVarName,
  472. new MethodCall{string(kDataVarName) + ".resizeOutVector",
  473. "&" + BuildVarName(*a)}});
  474. b->AddStatement(BreakOnStatusNotOk());
  475. }
  476. }
  477. if (options.GenTraces()) {
  478. b->AddStatement(new Statement(new MethodCall("atrace_begin",
  479. ArgList{{"ATRACE_TAG_AIDL",
  480. StringPrintf("\"%s::%s::cppServer\"",
  481. interface.GetName().c_str(),
  482. method.GetName().c_str())}})));
  483. }
  484. const string bn_name = ClassName(interface, ClassNames::SERVER);
  485. if (options.GenLog()) {
  486. b->AddLiteral(GenLogBeforeExecute(bn_name, method, true /* isServer */, false /* isNdk */),
  487. false);
  488. }
  489. // Call the actual method. This is implemented by the subclass.
  490. vector<unique_ptr<AstNode>> status_args;
  491. status_args.emplace_back(new MethodCall(
  492. method.GetName(),
  493. BuildArgList(types, method, false /* not for method decl */)));
  494. b->AddStatement(new Statement(new MethodCall(
  495. StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName),
  496. ArgList(std::move(status_args)))));
  497. if (options.GenTraces()) {
  498. b->AddStatement(new Statement(new MethodCall("atrace_end",
  499. "ATRACE_TAG_AIDL")));
  500. }
  501. if (options.GenLog()) {
  502. b->AddLiteral(GenLogAfterExecute(bn_name, interface, method, kStatusVarName, kReturnVarName,
  503. true /* isServer */, false /* isNdk */),
  504. false);
  505. }
  506. // Write exceptions during transaction handling to parcel.
  507. if (!method.IsOneway()) {
  508. b->AddStatement(new Assignment(
  509. kAndroidStatusVarName,
  510. StringPrintf("%s.writeToParcel(%s)", kStatusVarName, kReplyVarName)));
  511. b->AddStatement(BreakOnStatusNotOk());
  512. IfStatement* exception_check = new IfStatement(
  513. new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
  514. b->AddStatement(exception_check);
  515. exception_check->OnTrue()->AddLiteral("break");
  516. }
  517. // If we have a return value, write it first.
  518. if (return_type != types.VoidType()) {
  519. string writeMethod =
  520. string(kReplyVarName) + "->" +
  521. return_type->WriteToParcelMethod();
  522. b->AddStatement(new Assignment{
  523. kAndroidStatusVarName, new MethodCall{writeMethod,
  524. ArgList{return_type->WriteCast(kReturnVarName)}}});
  525. b->AddStatement(BreakOnStatusNotOk());
  526. }
  527. // Write each out parameter to the reply parcel.
  528. for (const AidlArgument* a : method.GetOutArguments()) {
  529. // Serialization looks roughly like:
  530. // _aidl_ret_status = data.WriteInt32(out_param_name);
  531. // if (_aidl_ret_status != ::android::OK) { break; }
  532. const Type* type = a->GetType().GetLanguageType<Type>();
  533. const string& writeMethod = type->WriteToParcelMethod();
  534. b->AddStatement(new Assignment{
  535. kAndroidStatusVarName,
  536. new MethodCall{string(kReplyVarName) + "->" + writeMethod,
  537. type->WriteCast(BuildVarName(*a))}});
  538. b->AddStatement(BreakOnStatusNotOk());
  539. }
  540. return true;
  541. }
  542. bool HandleServerMetaTransaction(const TypeNamespace&, const AidlInterface& interface,
  543. const AidlMethod& method, const Options& options,
  544. StatementBlock* b) {
  545. CHECK(!method.IsUserDefined());
  546. if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
  547. std::ostringstream code;
  548. code << "_aidl_data.checkInterface(this);\n"
  549. << "_aidl_reply->writeNoException();\n"
  550. << "_aidl_reply->writeInt32(" << ClassName(interface, ClassNames::INTERFACE)
  551. << "::VERSION)";
  552. b->AddLiteral(code.str());
  553. return true;
  554. }
  555. return false;
  556. }
  557. } // namespace
  558. unique_ptr<Document> BuildServerSource(const TypeNamespace& types, const AidlInterface& interface,
  559. const Options& options) {
  560. const string bn_name = ClassName(interface, ClassNames::SERVER);
  561. vector<string> include_list{
  562. HeaderFile(interface, ClassNames::SERVER, false),
  563. kParcelHeader
  564. };
  565. if (options.GenLog()) {
  566. include_list.emplace_back("chrono");
  567. include_list.emplace_back("functional");
  568. include_list.emplace_back("json/value.h");
  569. }
  570. unique_ptr<MethodImpl> on_transact{new MethodImpl{
  571. kAndroidStatusLiteral, bn_name, "onTransact",
  572. ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
  573. StringPrintf("const %s& %s", kAndroidParcelLiteral,
  574. kDataVarName),
  575. StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
  576. StringPrintf("uint32_t %s", kFlagsVarName)}}
  577. }};
  578. // Declare the status_t variable
  579. on_transact->GetStatementBlock()->AddLiteral(
  580. StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName,
  581. kAndroidStatusOk));
  582. // Add the all important switch statement, but retain a pointer to it.
  583. SwitchStatement* s = new SwitchStatement{kCodeVarName};
  584. on_transact->GetStatementBlock()->AddStatement(s);
  585. // The switch statement has a case statement for each transaction code.
  586. for (const auto& method : interface.GetMethods()) {
  587. StatementBlock* b = s->AddCase(GetTransactionIdFor(*method));
  588. if (!b) { return nullptr; }
  589. bool success = false;
  590. if (method->IsUserDefined()) {
  591. success = HandleServerTransaction(types, interface, *method, options, b);
  592. } else {
  593. success = HandleServerMetaTransaction(types, interface, *method, options, b);
  594. }
  595. if (!success) {
  596. return nullptr;
  597. }
  598. }
  599. // The switch statement has a default case which defers to the super class.
  600. // The superclass handles a few pre-defined transactions.
  601. StatementBlock* b = s->AddCase("");
  602. b->AddLiteral(StringPrintf(
  603. "%s = ::android::BBinder::onTransact(%s, %s, "
  604. "%s, %s)", kAndroidStatusVarName, kCodeVarName,
  605. kDataVarName, kReplyVarName, kFlagsVarName));
  606. // If we saw a null reference, we can map that to an appropriate exception.
  607. IfStatement* null_check = new IfStatement(
  608. new LiteralExpression(string(kAndroidStatusVarName) +
  609. " == ::android::UNEXPECTED_NULL"));
  610. on_transact->GetStatementBlock()->AddStatement(null_check);
  611. null_check->OnTrue()->AddStatement(new Assignment(
  612. kAndroidStatusVarName,
  613. StringPrintf("%s::fromExceptionCode(%s::EX_NULL_POINTER)"
  614. ".writeToParcel(%s)",
  615. kBinderStatusLiteral, kBinderStatusLiteral,
  616. kReplyVarName)));
  617. // Finally, the server's onTransact method just returns a status code.
  618. on_transact->GetStatementBlock()->AddLiteral(
  619. StringPrintf("return %s", kAndroidStatusVarName));
  620. vector<unique_ptr<Declaration>> decls;
  621. decls.push_back(std::move(on_transact));
  622. if (options.Version() > 0) {
  623. std::ostringstream code;
  624. code << "int32_t " << bn_name << "::" << kGetInterfaceVersion << "() {\n"
  625. << " return " << ClassName(interface, ClassNames::INTERFACE) << "::VERSION;\n"
  626. << "}\n";
  627. decls.emplace_back(new LiteralDecl(code.str()));
  628. }
  629. if (options.GenLog()) {
  630. string code;
  631. ClassName(interface, ClassNames::SERVER);
  632. CodeWriterPtr writer = CodeWriter::ForString(&code);
  633. (*writer) << "std::function<void(const Json::Value&)> "
  634. << ClassName(interface, ClassNames::SERVER) << "::logFunc;\n";
  635. writer->Close();
  636. decls.push_back(unique_ptr<Declaration>(new LiteralDecl(code)));
  637. }
  638. return unique_ptr<Document>{
  639. new CppSource{include_list, NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
  640. }
  641. unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& types,
  642. const AidlInterface& interface, const Options& options) {
  643. vector<string> include_list{
  644. HeaderFile(interface, ClassNames::RAW, false),
  645. HeaderFile(interface, ClassNames::CLIENT, false),
  646. };
  647. string fq_name = ClassName(interface, ClassNames::INTERFACE);
  648. if (!interface.GetPackage().empty()) {
  649. fq_name = interface.GetPackage() + "." + fq_name;
  650. }
  651. vector<unique_ptr<Declaration>> decls;
  652. unique_ptr<MacroDecl> meta_if{new MacroDecl{
  653. "IMPLEMENT_META_INTERFACE",
  654. ArgList{vector<string>{ClassName(interface, ClassNames::BASE),
  655. '"' + fq_name + '"'}}}};
  656. decls.push_back(std::move(meta_if));
  657. for (const auto& constant : interface.GetConstantDeclarations()) {
  658. const AidlConstantValue& value = constant->GetValue();
  659. if (value.GetType() != AidlConstantValue::Type::STRING) continue;
  660. std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
  661. unique_ptr<MethodImpl> getter(new MethodImpl("const " + cppType + "&",
  662. ClassName(interface, ClassNames::INTERFACE),
  663. constant->GetName(), {}));
  664. getter->GetStatementBlock()->AddLiteral(
  665. StringPrintf("static const %s value(%s)", cppType.c_str(),
  666. constant->ValueString(ConstantValueDecorator).c_str()));
  667. getter->GetStatementBlock()->AddLiteral("return value");
  668. decls.push_back(std::move(getter));
  669. }
  670. // Implement the default impl class.
  671. // onAsBinder returns nullptr as this interface is not associated with a
  672. // real binder.
  673. const string default_impl(ClassName(interface, ClassNames::DEFAULT_IMPL));
  674. decls.emplace_back(
  675. new LiteralDecl(StringPrintf("::android::IBinder* %s::onAsBinder() {\n"
  676. " return nullptr;\n"
  677. "}\n",
  678. default_impl.c_str())));
  679. // Each interface method by default returns UNKNOWN_TRANSACTION with is
  680. // the same status that is returned by transact() when the method is
  681. // not implemented in the server side. In other words, these default
  682. // methods do nothing; they only exist to aid making a real default
  683. // impl class without having to override all methods in an interface.
  684. for (const auto& method : interface.GetMethods()) {
  685. if (method->IsUserDefined()) {
  686. std::ostringstream code;
  687. code << "::android::binder::Status " << default_impl << "::" << method->GetName()
  688. << BuildArgList(types, *method, true, true).ToString() << " {\n"
  689. << " return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
  690. << "}\n";
  691. decls.emplace_back(new LiteralDecl(code.str()));
  692. } else {
  693. if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
  694. std::ostringstream code;
  695. code << "int32_t " << default_impl << "::" << kGetInterfaceVersion << "() {\n"
  696. << " return 0;\n"
  697. << "}\n";
  698. decls.emplace_back(new LiteralDecl(code.str()));
  699. }
  700. }
  701. }
  702. return unique_ptr<Document>{new CppSource{
  703. include_list,
  704. NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
  705. }
  706. unique_ptr<Document> BuildClientHeader(const TypeNamespace& types, const AidlInterface& interface,
  707. const Options& options) {
  708. const string i_name = ClassName(interface, ClassNames::INTERFACE);
  709. const string bp_name = ClassName(interface, ClassNames::CLIENT);
  710. vector<string> includes = {kIBinderHeader, kIInterfaceHeader, "utils/Errors.h",
  711. HeaderFile(interface, ClassNames::RAW, false)};
  712. unique_ptr<ConstructorDecl> constructor{new ConstructorDecl{
  713. bp_name,
  714. ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
  715. kImplVarName)},
  716. ConstructorDecl::IS_EXPLICIT
  717. }};
  718. unique_ptr<ConstructorDecl> destructor{new ConstructorDecl{
  719. "~" + bp_name,
  720. ArgList{},
  721. ConstructorDecl::IS_VIRTUAL | ConstructorDecl::IS_DEFAULT}};
  722. vector<unique_ptr<Declaration>> publics;
  723. publics.push_back(std::move(constructor));
  724. publics.push_back(std::move(destructor));
  725. for (const auto& method: interface.GetMethods()) {
  726. if (method->IsUserDefined()) {
  727. publics.push_back(BuildMethodDecl(*method, types, false));
  728. } else {
  729. publics.push_back(BuildMetaMethodDecl(*method, types, options, false));
  730. }
  731. }
  732. if (options.GenLog()) {
  733. includes.emplace_back("chrono"); // for std::chrono::steady_clock
  734. includes.emplace_back("functional"); // for std::function
  735. includes.emplace_back("json/value.h");
  736. publics.emplace_back(
  737. new LiteralDecl{"static std::function<void(const Json::Value&)> logFunc;\n"});
  738. }
  739. vector<unique_ptr<Declaration>> privates;
  740. if (options.Version() > 0) {
  741. privates.emplace_back(new LiteralDecl("int32_t cached_version_ = -1;\n"));
  742. }
  743. unique_ptr<ClassDecl> bp_class{new ClassDecl{
  744. bp_name,
  745. "::android::BpInterface<" + i_name + ">",
  746. std::move(publics),
  747. std::move(privates),
  748. }};
  749. return unique_ptr<Document>{
  750. new CppHeader{BuildHeaderGuard(interface, ClassNames::CLIENT), includes,
  751. NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}};
  752. }
  753. unique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */,
  754. const AidlInterface& interface, const Options& options) {
  755. const string i_name = ClassName(interface, ClassNames::INTERFACE);
  756. const string bn_name = ClassName(interface, ClassNames::SERVER);
  757. unique_ptr<Declaration> on_transact{new MethodDecl{
  758. kAndroidStatusLiteral, "onTransact",
  759. ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
  760. StringPrintf("const %s& %s", kAndroidParcelLiteral,
  761. kDataVarName),
  762. StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
  763. StringPrintf("uint32_t %s", kFlagsVarName)}},
  764. MethodDecl::IS_OVERRIDE
  765. }};
  766. vector<string> includes = {"binder/IInterface.h", HeaderFile(interface, ClassNames::RAW, false)};
  767. vector<unique_ptr<Declaration>> publics;
  768. publics.push_back(std::move(on_transact));
  769. if (options.Version() > 0) {
  770. std::ostringstream code;
  771. code << "int32_t " << kGetInterfaceVersion << "() final override;\n";
  772. publics.emplace_back(new LiteralDecl(code.str()));
  773. }
  774. if (options.GenLog()) {
  775. includes.emplace_back("chrono"); // for std::chrono::steady_clock
  776. includes.emplace_back("functional"); // for std::function
  777. includes.emplace_back("json/value.h");
  778. publics.emplace_back(
  779. new LiteralDecl{"static std::function<void(const Json::Value&)> logFunc;\n"});
  780. }
  781. unique_ptr<ClassDecl> bn_class{
  782. new ClassDecl{bn_name,
  783. "::android::BnInterface<" + i_name + ">",
  784. std::move(publics),
  785. {}
  786. }};
  787. return unique_ptr<Document>{
  788. new CppHeader{BuildHeaderGuard(interface, ClassNames::SERVER), includes,
  789. NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}};
  790. }
  791. unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
  792. const AidlInterface& interface, const Options& options) {
  793. set<string> includes = {kIBinderHeader, kIInterfaceHeader, kStatusHeader, kStrongPointerHeader};
  794. for (const auto& method : interface.GetMethods()) {
  795. for (const auto& argument : method->GetArguments()) {
  796. const Type* type = argument->GetType().GetLanguageType<Type>();
  797. type->GetHeaders(&includes);
  798. }
  799. const Type* return_type = method->GetType().GetLanguageType<Type>();
  800. if (return_type != nullptr) {
  801. return_type->GetHeaders(&includes);
  802. }
  803. }
  804. const string i_name = ClassName(interface, ClassNames::INTERFACE);
  805. unique_ptr<ClassDecl> if_class{new ClassDecl{i_name, "::android::IInterface"}};
  806. if_class->AddPublic(unique_ptr<Declaration>{new MacroDecl{
  807. "DECLARE_META_INTERFACE",
  808. ArgList{vector<string>{ClassName(interface, ClassNames::BASE)}}}});
  809. if (options.Version() > 0) {
  810. std::ostringstream code;
  811. code << "const int32_t VERSION = " << options.Version() << ";\n";
  812. if_class->AddPublic(unique_ptr<Declaration>(new LiteralDecl(code.str())));
  813. }
  814. std::vector<std::unique_ptr<Declaration>> string_constants;
  815. unique_ptr<Enum> int_constant_enum{new Enum{"", "int32_t"}};
  816. for (const auto& constant : interface.GetConstantDeclarations()) {
  817. const AidlConstantValue& value = constant->GetValue();
  818. switch (value.GetType()) {
  819. case AidlConstantValue::Type::STRING: {
  820. std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
  821. unique_ptr<Declaration> getter(new MethodDecl("const " + cppType + "&", constant->GetName(),
  822. {}, MethodDecl::IS_STATIC));
  823. string_constants.push_back(std::move(getter));
  824. break;
  825. }
  826. case AidlConstantValue::Type::INTEGRAL:
  827. case AidlConstantValue::Type::HEXIDECIMAL: {
  828. int_constant_enum->AddValue(constant->GetName(),
  829. constant->ValueString(ConstantValueDecorator));
  830. break;
  831. }
  832. default: {
  833. LOG(FATAL) << "Unrecognized constant type: " << static_cast<int>(value.GetType());
  834. }
  835. }
  836. }
  837. if (int_constant_enum->HasValues()) {
  838. if_class->AddPublic(std::move(int_constant_enum));
  839. }
  840. if (!string_constants.empty()) {
  841. includes.insert(kString16Header);
  842. for (auto& string_constant : string_constants) {
  843. if_class->AddPublic(std::move(string_constant));
  844. }
  845. }
  846. if (options.GenTraces()) {
  847. includes.insert(kTraceHeader);
  848. }
  849. if (!interface.GetMethods().empty()) {
  850. for (const auto& method : interface.GetMethods()) {
  851. if (method->IsUserDefined()) {
  852. // Each method gets an enum entry and pure virtual declaration.
  853. if_class->AddPublic(BuildMethodDecl(*method, types, true));
  854. } else {
  855. if_class->AddPublic(BuildMetaMethodDecl(*method, types, options, true));
  856. }
  857. }
  858. }
  859. vector<unique_ptr<Declaration>> decls;
  860. decls.emplace_back(std::move(if_class));
  861. // Base class for the default implementation.
  862. vector<string> method_decls;
  863. for (const auto& method : interface.GetMethods()) {
  864. if (method->IsUserDefined()) {
  865. method_decls.emplace_back(BuildMethodDecl(*method, types, false)->ToString());
  866. } else {
  867. method_decls.emplace_back(BuildMetaMethodDecl(*method, types, options, false)->ToString());
  868. }
  869. }
  870. decls.emplace_back(new LiteralDecl(
  871. android::base::StringPrintf("class %s : public %s {\n"
  872. "public:\n"
  873. " ::android::IBinder* onAsBinder() override;\n"
  874. " %s\n"
  875. "};\n",
  876. ClassName(interface, ClassNames::DEFAULT_IMPL).c_str(),
  877. i_name.c_str(), Join(method_decls, " ").c_str())));
  878. return unique_ptr<Document>{
  879. new CppHeader{BuildHeaderGuard(interface, ClassNames::INTERFACE),
  880. vector<string>(includes.begin(), includes.end()),
  881. NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
  882. }
  883. std::unique_ptr<Document> BuildParcelHeader(const TypeNamespace& /*types*/,
  884. const AidlStructuredParcelable& parcel,
  885. const Options&) {
  886. unique_ptr<ClassDecl> parcel_class{new ClassDecl{parcel.GetName(), "::android::Parcelable"}};
  887. set<string> includes = {kStatusHeader, kParcelHeader};
  888. for (const auto& variable : parcel.GetFields()) {
  889. const Type* type = variable->GetType().GetLanguageType<Type>();
  890. type->GetHeaders(&includes);
  891. }
  892. for (const auto& variable : parcel.GetFields()) {
  893. const Type* type = variable->GetType().GetLanguageType<Type>();
  894. std::ostringstream out;
  895. out << type->CppType().c_str() << " " << variable->GetName().c_str();
  896. if (variable->GetDefaultValue()) {
  897. out << " = " << type->CppType().c_str() << "("
  898. << variable->ValueString(ConstantValueDecorator) << ")";
  899. }
  900. out << ";\n";
  901. parcel_class->AddPublic(std::unique_ptr<LiteralDecl>(new LiteralDecl(out.str())));
  902. }
  903. unique_ptr<MethodDecl> read(new MethodDecl(kAndroidStatusLiteral, "readFromParcel",
  904. ArgList("const ::android::Parcel* _aidl_parcel"),
  905. MethodDecl::IS_OVERRIDE | MethodDecl::IS_FINAL));
  906. parcel_class->AddPublic(std::move(read));
  907. unique_ptr<MethodDecl> write(new MethodDecl(
  908. kAndroidStatusLiteral, "writeToParcel", ArgList("::android::Parcel* _aidl_parcel"),
  909. MethodDecl::IS_OVERRIDE | MethodDecl::IS_CONST | MethodDecl::IS_FINAL));
  910. parcel_class->AddPublic(std::move(write));
  911. return unique_ptr<Document>{new CppHeader{
  912. BuildHeaderGuard(parcel, ClassNames::BASE), vector<string>(includes.begin(), includes.end()),
  913. NestInNamespaces(std::move(parcel_class), parcel.GetSplitPackage())}};
  914. }
  915. std::unique_ptr<Document> BuildParcelSource(const TypeNamespace& /*types*/,
  916. const AidlStructuredParcelable& parcel,
  917. const Options&) {
  918. unique_ptr<MethodImpl> read{new MethodImpl{kAndroidStatusLiteral, parcel.GetName(),
  919. "readFromParcel",
  920. ArgList("const ::android::Parcel* _aidl_parcel")}};
  921. StatementBlock* read_block = read->GetStatementBlock();
  922. read_block->AddLiteral(
  923. StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk));
  924. read_block->AddLiteral(
  925. "size_t _aidl_start_pos = _aidl_parcel->dataPosition();\n"
  926. "int32_t _aidl_parcelable_raw_size = _aidl_parcel->readInt32();\n"
  927. "if (_aidl_parcelable_raw_size < 0) return ::android::BAD_VALUE;\n"
  928. "size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n");
  929. for (const auto& variable : parcel.GetFields()) {
  930. string method = variable->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
  931. read_block->AddStatement(new Assignment(
  932. kAndroidStatusVarName, new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
  933. ArgList("&" + variable->GetName()))));
  934. read_block->AddStatement(ReturnOnStatusNotOk());
  935. read_block->AddLiteral(StringPrintf(
  936. "if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n"
  937. " _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n"
  938. " return %s;\n"
  939. "}",
  940. kAndroidStatusVarName));
  941. }
  942. read_block->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName));
  943. unique_ptr<MethodImpl> write{
  944. new MethodImpl{kAndroidStatusLiteral, parcel.GetName(), "writeToParcel",
  945. ArgList("::android::Parcel* _aidl_parcel"), true /*const*/}};
  946. StatementBlock* write_block = write->GetStatementBlock();
  947. write_block->AddLiteral(
  948. StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk));
  949. write_block->AddLiteral(
  950. "auto _aidl_start_pos = _aidl_parcel->dataPosition();\n"
  951. "_aidl_parcel->writeInt32(0);");
  952. for (const auto& variable : parcel.GetFields()) {
  953. string method = variable->GetType().GetLanguageType<Type>()->WriteToParcelMethod();
  954. write_block->AddStatement(new Assignment(
  955. kAndroidStatusVarName, new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
  956. ArgList(variable->GetName()))));
  957. write_block->AddStatement(ReturnOnStatusNotOk());
  958. }
  959. write_block->AddLiteral(
  960. "auto _aidl_end_pos = _aidl_parcel->dataPosition();\n"
  961. "_aidl_parcel->setDataPosition(_aidl_start_pos);\n"
  962. "_aidl_parcel->writeInt32(_aidl_end_pos - _aidl_start_pos);\n"
  963. "_aidl_parcel->setDataPosition(_aidl_end_pos);");
  964. write_block->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName));
  965. vector<unique_ptr<Declaration>> file_decls;
  966. file_decls.push_back(std::move(read));
  967. file_decls.push_back(std::move(write));
  968. set<string> includes = {};
  969. parcel.GetLanguageType<Type>()->GetHeaders(&includes);
  970. return unique_ptr<Document>{
  971. new CppSource{vector<string>(includes.begin(), includes.end()),
  972. NestInNamespaces(std::move(file_decls), parcel.GetSplitPackage())}};
  973. }
  974. bool WriteHeader(const Options& options, const TypeNamespace& types, const AidlInterface& interface,
  975. const IoDelegate& io_delegate, ClassNames header_type) {
  976. unique_ptr<Document> header;
  977. switch (header_type) {
  978. case ClassNames::INTERFACE:
  979. header = BuildInterfaceHeader(types, interface, options);
  980. header_type = ClassNames::RAW;
  981. break;
  982. case ClassNames::CLIENT:
  983. header = BuildClientHeader(types, interface, options);
  984. break;
  985. case ClassNames::SERVER:
  986. header = BuildServerHeader(types, interface, options);
  987. break;
  988. default:
  989. LOG(FATAL) << "aidl internal error";
  990. }
  991. if (!header) {
  992. LOG(ERROR) << "aidl internal error: Failed to generate header.";
  993. return false;
  994. }
  995. const string header_path = options.OutputHeaderDir() + HeaderFile(interface, header_type);
  996. unique_ptr<CodeWriter> code_writer(io_delegate.GetCodeWriter(header_path));
  997. header->Write(code_writer.get());
  998. const bool success = code_writer->Close();
  999. if (!success) {
  1000. io_delegate.RemovePath(header_path);
  1001. }
  1002. return success;
  1003. }
  1004. } // namespace internals
  1005. using namespace internals;
  1006. bool GenerateCppInterface(const string& output_file, const Options& options,
  1007. const TypeNamespace& types, const AidlInterface& interface,
  1008. const IoDelegate& io_delegate) {
  1009. auto interface_src = BuildInterfaceSource(types, interface, options);
  1010. auto client_src = BuildClientSource(types, interface, options);
  1011. auto server_src = BuildServerSource(types, interface, options);
  1012. if (!interface_src || !client_src || !server_src) {
  1013. return false;
  1014. }
  1015. if (!WriteHeader(options, types, interface, io_delegate,
  1016. ClassNames::INTERFACE) ||
  1017. !WriteHeader(options, types, interface, io_delegate,
  1018. ClassNames::CLIENT) ||
  1019. !WriteHeader(options, types, interface, io_delegate,
  1020. ClassNames::SERVER)) {
  1021. return false;
  1022. }
  1023. unique_ptr<CodeWriter> writer = io_delegate.GetCodeWriter(output_file);
  1024. interface_src->Write(writer.get());
  1025. client_src->Write(writer.get());
  1026. server_src->Write(writer.get());
  1027. const bool success = writer->Close();
  1028. if (!success) {
  1029. io_delegate.RemovePath(output_file);
  1030. }
  1031. return success;
  1032. }
  1033. bool GenerateCppParcel(const string& output_file, const Options& options,
  1034. const cpp::TypeNamespace& types, const AidlStructuredParcelable& parcelable,
  1035. const IoDelegate& io_delegate) {
  1036. auto header = BuildParcelHeader(types, parcelable, options);
  1037. auto source = BuildParcelSource(types, parcelable, options);
  1038. if (!header || !source) {
  1039. return false;
  1040. }
  1041. const string header_path = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::RAW);
  1042. unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
  1043. header->Write(header_writer.get());
  1044. CHECK(header_writer->Close());
  1045. // TODO(b/111362593): no unecessary files just to have consistent output with interfaces
  1046. const string bp_header = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::CLIENT);
  1047. unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
  1048. bp_writer->Write("#error TODO(b/111362593) parcelables do not have bp classes");
  1049. CHECK(bp_writer->Close());
  1050. const string bn_header = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::SERVER);
  1051. unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
  1052. bn_writer->Write("#error TODO(b/111362593) parcelables do not have bn classes");
  1053. CHECK(bn_writer->Close());
  1054. unique_ptr<CodeWriter> source_writer = io_delegate.GetCodeWriter(output_file);
  1055. source->Write(source_writer.get());
  1056. CHECK(source_writer->Close());
  1057. return true;
  1058. }
  1059. bool GenerateCppParcelDeclaration(const std::string& filename, const IoDelegate& io_delegate) {
  1060. CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
  1061. *code_writer
  1062. << "// This file is intentionally left blank as placeholder for parcel declaration.\n";
  1063. return true;
  1064. }
  1065. bool GenerateCpp(const string& output_file, const Options& options, const TypeNamespace& types,
  1066. const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
  1067. const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
  1068. if (parcelable != nullptr) {
  1069. return GenerateCppParcel(output_file, options, types, *parcelable, io_delegate);
  1070. }
  1071. const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
  1072. if (parcelable_decl != nullptr) {
  1073. return GenerateCppParcelDeclaration(output_file, io_delegate);
  1074. }
  1075. const AidlInterface* interface = defined_type.AsInterface();
  1076. if (interface != nullptr) {
  1077. return GenerateCppInterface(output_file, options, types, *interface, io_delegate);
  1078. }
  1079. CHECK(false) << "Unrecognized type sent for cpp generation.";
  1080. return false;
  1081. }
  1082. } // namespace cpp
  1083. } // namespace aidl
  1084. } // namespace android