Home | History | Annotate | Download | only in aidl
      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 
     19 #include <cctype>
     20 #include <cstring>
     21 #include <memory>
     22 #include <random>
     23 #include <set>
     24 #include <string>
     25 
     26 #include <android-base/stringprintf.h>
     27 
     28 #include "aidl_language.h"
     29 #include "ast_cpp.h"
     30 #include "code_writer.h"
     31 #include "logging.h"
     32 #include "os.h"
     33 
     34 using android::base::StringPrintf;
     35 using std::string;
     36 using std::unique_ptr;
     37 using std::vector;
     38 using std::set;
     39 
     40 namespace android {
     41 namespace aidl {
     42 namespace cpp {
     43 namespace internals {
     44 namespace {
     45 
     46 const char kAndroidStatusVarName[] = "_aidl_ret_status";
     47 const char kCodeVarName[] = "_aidl_code";
     48 const char kFlagsVarName[] = "_aidl_flags";
     49 const char kDataVarName[] = "_aidl_data";
     50 const char kErrorLabel[] = "_aidl_error";
     51 const char kImplVarName[] = "_aidl_impl";
     52 const char kReplyVarName[] = "_aidl_reply";
     53 const char kReturnVarName[] = "_aidl_return";
     54 const char kStatusVarName[] = "_aidl_status";
     55 const char kAndroidParcelLiteral[] = "::android::Parcel";
     56 const char kAndroidStatusLiteral[] = "::android::status_t";
     57 const char kAndroidStatusOk[] = "::android::OK";
     58 const char kBinderStatusLiteral[] = "::android::binder::Status";
     59 const char kIBinderHeader[] = "binder/IBinder.h";
     60 const char kIInterfaceHeader[] = "binder/IInterface.h";
     61 const char kParcelHeader[] = "binder/Parcel.h";
     62 const char kStatusHeader[] = "binder/Status.h";
     63 const char kString16Header[] = "utils/String16.h";
     64 const char kStrongPointerHeader[] = "utils/StrongPointer.h";
     65 
     66 unique_ptr<AstNode> BreakOnStatusNotOk() {
     67   IfStatement* ret = new IfStatement(new Comparison(
     68       new LiteralExpression(kAndroidStatusVarName), "!=",
     69       new LiteralExpression(kAndroidStatusOk)));
     70   ret->OnTrue()->AddLiteral("break");
     71   return unique_ptr<AstNode>(ret);
     72 }
     73 
     74 unique_ptr<AstNode> GotoErrorOnBadStatus() {
     75   IfStatement* ret = new IfStatement(new Comparison(
     76       new LiteralExpression(kAndroidStatusVarName), "!=",
     77       new LiteralExpression(kAndroidStatusOk)));
     78   ret->OnTrue()->AddLiteral(StringPrintf("goto %s", kErrorLabel));
     79   return unique_ptr<AstNode>(ret);
     80 }
     81 
     82 
     83 unique_ptr<AstNode> ReturnOnStatusNotOk() {
     84   IfStatement* ret = new IfStatement(new Comparison(
     85       new LiteralExpression(kAndroidStatusVarName), "!=",
     86       new LiteralExpression(kAndroidStatusOk)));
     87   ret->OnTrue()->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName));
     88   return unique_ptr<AstNode>(ret);
     89 }
     90 
     91 string UpperCase(const std::string& s) {
     92   string result = s;
     93   for (char& c : result)
     94     c = toupper(c);
     95   return result;
     96 }
     97 
     98 string BuildVarName(const AidlArgument& a) {
     99   string prefix = "out_";
    100   if (a.GetDirection() & AidlArgument::IN_DIR) {
    101     prefix = "in_";
    102   }
    103   return prefix + a.GetName();
    104 }
    105 
    106 ArgList BuildArgList(const TypeNamespace& types,
    107                      const AidlMethod& method,
    108                      bool for_declaration) {
    109   // Build up the argument list for the server method call.
    110   vector<string> method_arguments;
    111   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
    112     string literal;
    113     if (for_declaration) {
    114       // Method declarations need types, pointers to out params, and variable
    115       // names that match the .aidl specification.
    116       const Type* type = a->GetType().GetLanguageType<Type>();
    117 
    118       literal = type->CppType();
    119 
    120       if (a->IsOut()) {
    121         literal = literal + "*";
    122       } else {
    123         // We pass in parameters that are not primitives by const reference.
    124         // Arrays of primitives are not primitives.
    125         if (!type->IsCppPrimitive() || a->GetType().IsArray()) {
    126           literal = "const " + literal + "&";
    127         }
    128       }
    129 
    130       literal += " " + a->GetName();
    131     } else {
    132       if (a->IsOut()) { literal = "&"; }
    133       literal += BuildVarName(*a);
    134     }
    135     method_arguments.push_back(literal);
    136   }
    137 
    138   const Type* return_type = method.GetType().GetLanguageType<Type>();
    139 
    140   if (return_type != types.VoidType()) {
    141     string literal;
    142     if (for_declaration) {
    143       literal = StringPrintf(
    144           "%s* %s", return_type->CppType().c_str(),
    145           kReturnVarName);
    146     } else {
    147       literal = string{"&"} + kReturnVarName;
    148     }
    149     method_arguments.push_back(literal);
    150   }
    151 
    152   return ArgList(method_arguments);
    153 }
    154 
    155 unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
    156                                         const TypeNamespace& types,
    157                                         bool for_interface) {
    158   uint32_t modifiers = 0;
    159   if (for_interface) {
    160     modifiers |= MethodDecl::IS_VIRTUAL;
    161     modifiers |= MethodDecl::IS_PURE_VIRTUAL;
    162   } else {
    163     modifiers |= MethodDecl::IS_OVERRIDE;
    164   }
    165 
    166   return unique_ptr<Declaration>{
    167       new MethodDecl{kBinderStatusLiteral,
    168                      method.GetName(),
    169                      BuildArgList(types, method, true /* for method decl */),
    170                      modifiers}};
    171 }
    172 
    173 unique_ptr<CppNamespace> NestInNamespaces(
    174     vector<unique_ptr<Declaration>> decls,
    175     const vector<string>& package) {
    176   if (package.empty()) {
    177     // We should also be checking this before we get this far, but do it again
    178     // for the sake of unit tests and meaningful errors.
    179     LOG(FATAL) << "C++ generation requires a package declaration "
    180                   "for namespacing";
    181   }
    182   auto it = package.crbegin();  // Iterate over the namespaces inner to outer
    183   unique_ptr<CppNamespace> inner{new CppNamespace{*it, std::move(decls)}};
    184   ++it;
    185   for (; it != package.crend(); ++it) {
    186     inner.reset(new CppNamespace{*it, std::move(inner)});
    187   }
    188   return inner;
    189 }
    190 
    191 unique_ptr<CppNamespace> NestInNamespaces(unique_ptr<Declaration> decl,
    192                                           const vector<string>& package) {
    193   vector<unique_ptr<Declaration>> decls;
    194   decls.push_back(std::move(decl));
    195   return NestInNamespaces(std::move(decls), package);
    196 }
    197 
    198 bool DeclareLocalVariable(const TypeNamespace& types, const AidlArgument& a,
    199                           StatementBlock* b) {
    200   const Type* cpp_type = a.GetType().GetLanguageType<Type>();
    201   if (!cpp_type) { return false; }
    202 
    203   string type = cpp_type->CppType();
    204 
    205   b->AddLiteral(type + " " + BuildVarName(a));
    206   return true;
    207 }
    208 
    209 string ClassName(const AidlInterface& interface, ClassNames type) {
    210   string c_name = interface.GetName();
    211 
    212   if (c_name.length() >= 2 && c_name[0] == 'I' && isupper(c_name[1]))
    213     c_name = c_name.substr(1);
    214 
    215   switch (type) {
    216     case ClassNames::CLIENT:
    217       c_name = "Bp" + c_name;
    218       break;
    219     case ClassNames::SERVER:
    220       c_name = "Bn" + c_name;
    221       break;
    222     case ClassNames::INTERFACE:
    223       c_name = "I" + c_name;
    224       break;
    225     case ClassNames::BASE:
    226       break;
    227   }
    228   return c_name;
    229 }
    230 
    231 string BuildHeaderGuard(const AidlInterface& interface,
    232                         ClassNames header_type) {
    233   string class_name = ClassName(interface, header_type);
    234   for (size_t i = 1; i < class_name.size(); ++i) {
    235     if (isupper(class_name[i])) {
    236       class_name.insert(i, "_");
    237       ++i;
    238     }
    239   }
    240   string ret = StringPrintf("AIDL_GENERATED_%s_%s_H_",
    241                             interface.GetPackage().c_str(),
    242                             class_name.c_str());
    243   for (char& c : ret) {
    244     if (c == '.') {
    245       c = '_';
    246     }
    247     c = toupper(c);
    248   }
    249   return ret;
    250 }
    251 
    252 unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types,
    253                                                 const AidlInterface& interface,
    254                                                 const AidlMethod& method) {
    255   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    256   const string bp_name = ClassName(interface, ClassNames::CLIENT);
    257   unique_ptr<MethodImpl> ret{new MethodImpl{
    258       kBinderStatusLiteral, bp_name, method.GetName(),
    259       ArgList{BuildArgList(types, method, true /* for method decl */)}}};
    260   StatementBlock* b = ret->GetStatementBlock();
    261 
    262   // Declare parcels to hold our query and the response.
    263   b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kDataVarName));
    264   // Even if we're oneway, the transact method still takes a parcel.
    265   b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kReplyVarName));
    266 
    267   // Declare the status_t variable we need for error handling.
    268   b->AddLiteral(StringPrintf("%s %s = %s", kAndroidStatusLiteral,
    269                              kAndroidStatusVarName,
    270                              kAndroidStatusOk));
    271   // We unconditionally return a Status object.
    272   b->AddLiteral(StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName));
    273 
    274   // Add the name of the interface we're hoping to call.
    275   b->AddStatement(new Assignment(
    276       kAndroidStatusVarName,
    277       new MethodCall(StringPrintf("%s.writeInterfaceToken",
    278                                   kDataVarName),
    279                      "getInterfaceDescriptor()")));
    280   b->AddStatement(GotoErrorOnBadStatus());
    281 
    282   for (const auto& a: method.GetArguments()) {
    283     const Type* type = a->GetType().GetLanguageType<Type>();
    284     string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
    285     var_name = type->WriteCast(var_name);
    286 
    287     if (a->IsIn()) {
    288       // Serialization looks roughly like:
    289       //     _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
    290       //     if (_aidl_ret_status != ::android::OK) { goto error; }
    291       const string& method = type->WriteToParcelMethod();
    292       b->AddStatement(new Assignment(
    293           kAndroidStatusVarName,
    294           new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
    295                          ArgList(var_name))));
    296       b->AddStatement(GotoErrorOnBadStatus());
    297     } else if (a->IsOut() && a->GetType().IsArray()) {
    298       // Special case, the length of the out array is written into the parcel.
    299       //     _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
    300       //     if (_aidl_ret_status != ::android::OK) { goto error; }
    301       b->AddStatement(new Assignment(
    302           kAndroidStatusVarName,
    303           new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName),
    304                          ArgList(var_name))));
    305       b->AddStatement(GotoErrorOnBadStatus());
    306     }
    307   }
    308 
    309   // Invoke the transaction on the remote binder and confirm status.
    310   string transaction_code = StringPrintf(
    311       "%s::%s", i_name.c_str(), UpperCase(method.GetName()).c_str());
    312 
    313   vector<string> args = {transaction_code, kDataVarName,
    314                          StringPrintf("&%s", kReplyVarName)};
    315 
    316   if (interface.IsOneway() || method.IsOneway()) {
    317     args.push_back("::android::IBinder::FLAG_ONEWAY");
    318   }
    319 
    320   b->AddStatement(new Assignment(
    321       kAndroidStatusVarName,
    322       new MethodCall("remote()->transact",
    323                      ArgList(args))));
    324   b->AddStatement(GotoErrorOnBadStatus());
    325 
    326   if (!interface.IsOneway() && !method.IsOneway()) {
    327     // Strip off the exception header and fail if we see a remote exception.
    328     // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
    329     // if (_aidl_ret_status != ::android::OK) { goto error; }
    330     // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
    331     b->AddStatement(new Assignment(
    332         kAndroidStatusVarName,
    333         StringPrintf("%s.readFromParcel(%s)", kStatusVarName, kReplyVarName)));
    334     b->AddStatement(GotoErrorOnBadStatus());
    335     IfStatement* exception_check = new IfStatement(
    336         new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
    337     b->AddStatement(exception_check);
    338     exception_check->OnTrue()->AddLiteral(
    339         StringPrintf("return %s", kStatusVarName));
    340   }
    341 
    342   // Type checking should guarantee that nothing below emits code until "return
    343   // status" if we are a oneway method, so no more fear of accessing reply.
    344 
    345   // If the method is expected to return something, read it first by convention.
    346   const Type* return_type = method.GetType().GetLanguageType<Type>();
    347   if (return_type != types.VoidType()) {
    348     const string& method_call = return_type->ReadFromParcelMethod();
    349     b->AddStatement(new Assignment(
    350         kAndroidStatusVarName,
    351         new MethodCall(StringPrintf("%s.%s", kReplyVarName,
    352                                     method_call.c_str()),
    353                        ArgList(kReturnVarName))));
    354     b->AddStatement(GotoErrorOnBadStatus());
    355   }
    356 
    357   for (const AidlArgument* a : method.GetOutArguments()) {
    358     // Deserialization looks roughly like:
    359     //     _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
    360     //     if (_aidl_status != ::android::OK) { goto _aidl_error; }
    361     string method =
    362       a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
    363 
    364     b->AddStatement(new Assignment(
    365         kAndroidStatusVarName,
    366         new MethodCall(StringPrintf("%s.%s", kReplyVarName,
    367                                     method.c_str()),
    368                        ArgList(a->GetName()))));
    369     b->AddStatement(GotoErrorOnBadStatus());
    370   }
    371 
    372   // If we've gotten to here, one of two things is true:
    373   //   1) We've read some bad status_t
    374   //   2) We've only read status_t == OK and there was no exception in the
    375   //      response.
    376   // In both cases, we're free to set Status from the status_t and return.
    377   b->AddLiteral(StringPrintf("%s:\n", kErrorLabel), false /* no semicolon */);
    378   b->AddLiteral(
    379       StringPrintf("%s.setFromStatusT(%s)", kStatusVarName,
    380                    kAndroidStatusVarName));
    381   b->AddLiteral(StringPrintf("return %s", kStatusVarName));
    382 
    383   return unique_ptr<Declaration>(ret.release());
    384 }
    385 
    386 }  // namespace
    387 
    388 unique_ptr<Document> BuildClientSource(const TypeNamespace& types,
    389                                        const AidlInterface& interface) {
    390   vector<string> include_list = {
    391       HeaderFile(interface, ClassNames::CLIENT, false),
    392       kParcelHeader
    393   };
    394   vector<unique_ptr<Declaration>> file_decls;
    395 
    396   // The constructor just passes the IBinder instance up to the super
    397   // class.
    398   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    399   file_decls.push_back(unique_ptr<Declaration>{new ConstructorImpl{
    400       ClassName(interface, ClassNames::CLIENT),
    401       ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
    402                            kImplVarName)},
    403       { "BpInterface<" + i_name + ">(" + kImplVarName + ")" }}});
    404 
    405   // Clients define a method per transaction.
    406   for (const auto& method : interface.GetMethods()) {
    407     unique_ptr<Declaration> m = DefineClientTransaction(
    408         types, interface, *method);
    409     if (!m) { return nullptr; }
    410     file_decls.push_back(std::move(m));
    411   }
    412   return unique_ptr<Document>{new CppSource{
    413       include_list,
    414       NestInNamespaces(std::move(file_decls), interface.GetSplitPackage())}};
    415 }
    416 
    417 namespace {
    418 
    419 bool HandleServerTransaction(const TypeNamespace& types,
    420                              const AidlMethod& method,
    421                              StatementBlock* b) {
    422   // Declare all the parameters now.  In the common case, we expect no errors
    423   // in serialization.
    424   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
    425     if (!DeclareLocalVariable(types, *a, b)) { return false; }
    426   }
    427 
    428   // Declare a variable to hold the return value.
    429   const Type* return_type = method.GetType().GetLanguageType<Type>();
    430   if (return_type != types.VoidType()) {
    431     b->AddLiteral(StringPrintf(
    432         "%s %s", return_type->CppType().c_str(),
    433         kReturnVarName));
    434   }
    435 
    436   // Check that the client is calling the correct interface.
    437   IfStatement* interface_check = new IfStatement(
    438       new MethodCall(StringPrintf("%s.checkInterface",
    439                                   kDataVarName), "this"),
    440       true /* invert the check */);
    441   b->AddStatement(interface_check);
    442   interface_check->OnTrue()->AddStatement(
    443       new Assignment(kAndroidStatusVarName, "::android::BAD_TYPE"));
    444   interface_check->OnTrue()->AddLiteral("break");
    445 
    446   // Deserialize each "in" parameter to the transaction.
    447   for (const auto& a: method.GetArguments()) {
    448     // Deserialization looks roughly like:
    449     //     _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
    450     //     if (_aidl_ret_status != ::android::OK) { break; }
    451     const Type* type = a->GetType().GetLanguageType<Type>();
    452     const string& readMethod = type->ReadFromParcelMethod();
    453 
    454     if (a->IsIn()) {
    455       b->AddStatement(new Assignment{
    456           kAndroidStatusVarName,
    457           new MethodCall{string(kDataVarName) + "." + readMethod,
    458                          "&" + BuildVarName(*a)}});
    459       b->AddStatement(BreakOnStatusNotOk());
    460     } else if (a->IsOut() && a->GetType().IsArray()) {
    461       // Special case, the length of the out array is written into the parcel.
    462       //     _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
    463       //     if (_aidl_ret_status != ::android::OK) { break; }
    464       b->AddStatement(new Assignment{
    465           kAndroidStatusVarName,
    466           new MethodCall{string(kDataVarName) + ".resizeOutVector",
    467                          "&" + BuildVarName(*a)}});
    468       b->AddStatement(BreakOnStatusNotOk());
    469     }
    470   }
    471 
    472   // Call the actual method.  This is implemented by the subclass.
    473   vector<unique_ptr<AstNode>> status_args;
    474   status_args.emplace_back(new MethodCall(
    475           method.GetName(),
    476           BuildArgList(types, method, false /* not for method decl */)));
    477   b->AddStatement(new Statement(new MethodCall(
    478       StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName),
    479       ArgList(std::move(status_args)))));
    480 
    481   // Write exceptions during transaction handling to parcel.
    482   if (!method.IsOneway()) {
    483     b->AddStatement(new Assignment(
    484         kAndroidStatusVarName,
    485         StringPrintf("%s.writeToParcel(%s)", kStatusVarName, kReplyVarName)));
    486     b->AddStatement(BreakOnStatusNotOk());
    487     IfStatement* exception_check = new IfStatement(
    488         new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
    489     b->AddStatement(exception_check);
    490     exception_check->OnTrue()->AddLiteral("break");
    491   }
    492 
    493   // If we have a return value, write it first.
    494   if (return_type != types.VoidType()) {
    495     string writeMethod =
    496         string(kReplyVarName) + "->" +
    497         return_type->WriteToParcelMethod();
    498     b->AddStatement(new Assignment{
    499         kAndroidStatusVarName, new MethodCall{writeMethod,
    500         ArgList{return_type->WriteCast(kReturnVarName)}}});
    501     b->AddStatement(BreakOnStatusNotOk());
    502   }
    503 
    504   // Write each out parameter to the reply parcel.
    505   for (const AidlArgument* a : method.GetOutArguments()) {
    506     // Serialization looks roughly like:
    507     //     _aidl_ret_status = data.WriteInt32(out_param_name);
    508     //     if (_aidl_ret_status != ::android::OK) { break; }
    509     const Type* type = a->GetType().GetLanguageType<Type>();
    510     const string& writeMethod = type->WriteToParcelMethod();
    511 
    512     b->AddStatement(new Assignment{
    513         kAndroidStatusVarName,
    514         new MethodCall{string(kReplyVarName) + "->" + writeMethod,
    515                        type->WriteCast(BuildVarName(*a))}});
    516     b->AddStatement(BreakOnStatusNotOk());
    517   }
    518 
    519   return true;
    520 }
    521 
    522 }  // namespace
    523 
    524 unique_ptr<Document> BuildServerSource(const TypeNamespace& types,
    525                                        const AidlInterface& interface) {
    526   const string bn_name = ClassName(interface, ClassNames::SERVER);
    527   vector<string> include_list{
    528       HeaderFile(interface, ClassNames::SERVER, false),
    529       kParcelHeader
    530   };
    531   unique_ptr<MethodImpl> on_transact{new MethodImpl{
    532       kAndroidStatusLiteral, bn_name, "onTransact",
    533       ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
    534                StringPrintf("const %s& %s", kAndroidParcelLiteral,
    535                             kDataVarName),
    536                StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
    537                StringPrintf("uint32_t %s", kFlagsVarName)}}
    538       }};
    539 
    540   // Declare the status_t variable
    541   on_transact->GetStatementBlock()->AddLiteral(
    542       StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName,
    543                    kAndroidStatusOk));
    544 
    545   // Add the all important switch statement, but retain a pointer to it.
    546   SwitchStatement* s = new SwitchStatement{kCodeVarName};
    547   on_transact->GetStatementBlock()->AddStatement(s);
    548 
    549   // The switch statement has a case statement for each transaction code.
    550   for (const auto& method : interface.GetMethods()) {
    551     StatementBlock* b = s->AddCase("Call::" + UpperCase(method->GetName()));
    552     if (!b) { return nullptr; }
    553 
    554     if (!HandleServerTransaction(types, *method, b)) { return nullptr; }
    555   }
    556 
    557   // The switch statement has a default case which defers to the super class.
    558   // The superclass handles a few pre-defined transactions.
    559   StatementBlock* b = s->AddCase("");
    560   b->AddLiteral(StringPrintf(
    561                 "%s = ::android::BBinder::onTransact(%s, %s, "
    562                 "%s, %s)", kAndroidStatusVarName, kCodeVarName,
    563                 kDataVarName, kReplyVarName, kFlagsVarName));
    564 
    565   // If we saw a null reference, we can map that to an appropriate exception.
    566   IfStatement* null_check = new IfStatement(
    567       new LiteralExpression(string(kAndroidStatusVarName) +
    568                             " == ::android::UNEXPECTED_NULL"));
    569   on_transact->GetStatementBlock()->AddStatement(null_check);
    570   null_check->OnTrue()->AddStatement(new Assignment(
    571       kAndroidStatusVarName,
    572       StringPrintf("%s::fromExceptionCode(%s::EX_NULL_POINTER)"
    573                    ".writeToParcel(%s)",
    574                    kBinderStatusLiteral, kBinderStatusLiteral,
    575                    kReplyVarName)));
    576 
    577   // Finally, the server's onTransact method just returns a status code.
    578   on_transact->GetStatementBlock()->AddLiteral(
    579       StringPrintf("return %s", kAndroidStatusVarName));
    580 
    581   return unique_ptr<Document>{new CppSource{
    582       include_list,
    583       NestInNamespaces(std::move(on_transact), interface.GetSplitPackage())}};
    584 }
    585 
    586 unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& /* types */,
    587                                           const AidlInterface& interface) {
    588   vector<string> include_list{
    589       HeaderFile(interface, ClassNames::INTERFACE, false),
    590       HeaderFile(interface, ClassNames::CLIENT, false),
    591   };
    592 
    593   string fq_name = ClassName(interface, ClassNames::INTERFACE);
    594   if (!interface.GetPackage().empty()) {
    595     fq_name = interface.GetPackage() + "." + fq_name;
    596   }
    597 
    598   vector<unique_ptr<Declaration>> decls;
    599 
    600   unique_ptr<MacroDecl> meta_if{new MacroDecl{
    601       "IMPLEMENT_META_INTERFACE",
    602       ArgList{vector<string>{ClassName(interface, ClassNames::BASE),
    603                              '"' + fq_name + '"'}}}};
    604   decls.push_back(std::move(meta_if));
    605 
    606   for (const auto& constant: interface.GetStringConstants()) {
    607     unique_ptr<MethodImpl> getter(new MethodImpl(
    608         "const ::android::String16&",
    609         ClassName(interface, ClassNames::INTERFACE),
    610         constant->GetName(),
    611         {}));
    612     getter->GetStatementBlock()->AddLiteral(
    613         StringPrintf("static const ::android::String16 value(%s)",
    614                      constant->GetValue().c_str()));
    615     getter->GetStatementBlock()->AddLiteral("return value");
    616     decls.push_back(std::move(getter));
    617   }
    618 
    619   return unique_ptr<Document>{new CppSource{
    620       include_list,
    621       NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
    622 }
    623 
    624 unique_ptr<Document> BuildClientHeader(const TypeNamespace& types,
    625                                        const AidlInterface& interface) {
    626   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    627   const string bp_name = ClassName(interface, ClassNames::CLIENT);
    628 
    629   unique_ptr<ConstructorDecl> constructor{new ConstructorDecl{
    630       bp_name,
    631       ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
    632                            kImplVarName)},
    633       ConstructorDecl::IS_EXPLICIT
    634   }};
    635   unique_ptr<ConstructorDecl> destructor{new ConstructorDecl{
    636       "~" + bp_name,
    637       ArgList{},
    638       ConstructorDecl::IS_VIRTUAL | ConstructorDecl::IS_DEFAULT}};
    639 
    640   vector<unique_ptr<Declaration>> publics;
    641   publics.push_back(std::move(constructor));
    642   publics.push_back(std::move(destructor));
    643 
    644   for (const auto& method: interface.GetMethods()) {
    645     publics.push_back(BuildMethodDecl(*method, types, false));
    646   }
    647 
    648   unique_ptr<ClassDecl> bp_class{
    649       new ClassDecl{bp_name,
    650                     "::android::BpInterface<" + i_name + ">",
    651                     std::move(publics),
    652                     {}
    653       }};
    654 
    655   return unique_ptr<Document>{new CppHeader{
    656       BuildHeaderGuard(interface, ClassNames::CLIENT),
    657       {kIBinderHeader,
    658        kIInterfaceHeader,
    659        "utils/Errors.h",
    660        HeaderFile(interface, ClassNames::INTERFACE, false)},
    661       NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}};
    662 }
    663 
    664 unique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */,
    665                                        const AidlInterface& interface) {
    666   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    667   const string bn_name = ClassName(interface, ClassNames::SERVER);
    668 
    669   unique_ptr<Declaration> on_transact{new MethodDecl{
    670       kAndroidStatusLiteral, "onTransact",
    671       ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
    672                StringPrintf("const %s& %s", kAndroidParcelLiteral,
    673                             kDataVarName),
    674                StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
    675                StringPrintf("uint32_t %s = 0", kFlagsVarName)}},
    676       MethodDecl::IS_OVERRIDE
    677   }};
    678 
    679   std::vector<unique_ptr<Declaration>> publics;
    680   publics.push_back(std::move(on_transact));
    681 
    682   unique_ptr<ClassDecl> bn_class{
    683       new ClassDecl{bn_name,
    684                     "::android::BnInterface<" + i_name + ">",
    685                     std::move(publics),
    686                     {}
    687       }};
    688 
    689   return unique_ptr<Document>{new CppHeader{
    690       BuildHeaderGuard(interface, ClassNames::SERVER),
    691       {"binder/IInterface.h",
    692        HeaderFile(interface, ClassNames::INTERFACE, false)},
    693       NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}};
    694 }
    695 
    696 unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
    697                                           const AidlInterface& interface) {
    698   set<string> includes = { kIBinderHeader, kIInterfaceHeader,
    699                            kStatusHeader, kStrongPointerHeader };
    700 
    701   for (const auto& method : interface.GetMethods()) {
    702     for (const auto& argument : method->GetArguments()) {
    703       const Type* type = argument->GetType().GetLanguageType<Type>();
    704       type->GetHeaders(&includes);
    705     }
    706 
    707     const Type* return_type = method->GetType().GetLanguageType<Type>();
    708     return_type->GetHeaders(&includes);
    709   }
    710 
    711   unique_ptr<ClassDecl> if_class{
    712       new ClassDecl{ClassName(interface, ClassNames::INTERFACE),
    713                     "::android::IInterface"}};
    714   if_class->AddPublic(unique_ptr<Declaration>{new MacroDecl{
    715       "DECLARE_META_INTERFACE",
    716       ArgList{vector<string>{ClassName(interface, ClassNames::BASE)}}}});
    717 
    718   unique_ptr<Enum> constant_enum{new Enum{"", "int32_t"}};
    719   for (const auto& constant : interface.GetIntConstants()) {
    720     constant_enum->AddValue(
    721         constant->GetName(), std::to_string(constant->GetValue()));
    722   }
    723   if (constant_enum->HasValues()) {
    724     if_class->AddPublic(std::move(constant_enum));
    725   }
    726 
    727   if (!interface.GetStringConstants().empty()) {
    728     includes.insert(kString16Header);
    729   }
    730   for (const auto& constant : interface.GetStringConstants()) {
    731     unique_ptr<MethodDecl> getter(new MethodDecl(
    732           "const ::android::String16&", constant->GetName(),
    733           {}, MethodDecl::IS_STATIC));
    734     if_class->AddPublic(std::move(getter));
    735   }
    736 
    737   if (!interface.GetMethods().empty()) {
    738     unique_ptr<Enum> call_enum{new Enum{"Call"}};
    739     for (const auto& method : interface.GetMethods()) {
    740       // Each method gets an enum entry and pure virtual declaration.
    741       if_class->AddPublic(BuildMethodDecl(*method, types, true));
    742       call_enum->AddValue(
    743           UpperCase(method->GetName()),
    744           StringPrintf("::android::IBinder::FIRST_CALL_TRANSACTION + %d",
    745                        method->GetId()));
    746     }
    747     if_class->AddPublic(std::move(call_enum));
    748   }
    749 
    750   return unique_ptr<Document>{new CppHeader{
    751       BuildHeaderGuard(interface, ClassNames::INTERFACE),
    752       vector<string>(includes.begin(), includes.end()),
    753       NestInNamespaces(std::move(if_class), interface.GetSplitPackage())}};
    754 }
    755 
    756 bool WriteHeader(const CppOptions& options,
    757                  const TypeNamespace& types,
    758                  const AidlInterface& interface,
    759                  const IoDelegate& io_delegate,
    760                  ClassNames header_type) {
    761   unique_ptr<Document> header;
    762   switch (header_type) {
    763     case ClassNames::INTERFACE:
    764       header = BuildInterfaceHeader(types, interface);
    765       break;
    766     case ClassNames::CLIENT:
    767       header = BuildClientHeader(types, interface);
    768       break;
    769     case ClassNames::SERVER:
    770       header = BuildServerHeader(types, interface);
    771       break;
    772     default:
    773       LOG(FATAL) << "aidl internal error";
    774   }
    775   if (!header) {
    776     LOG(ERROR) << "aidl internal error: Failed to generate header.";
    777     return false;
    778   }
    779 
    780   const string header_path = options.OutputHeaderDir() + OS_PATH_SEPARATOR +
    781                              HeaderFile(interface, header_type);
    782   unique_ptr<CodeWriter> code_writer(io_delegate.GetCodeWriter(header_path));
    783   header->Write(code_writer.get());
    784 
    785   const bool success = code_writer->Close();
    786   if (!success) {
    787     io_delegate.RemovePath(header_path);
    788   }
    789 
    790   return success;
    791 }
    792 
    793 }  // namespace internals
    794 
    795 using namespace internals;
    796 
    797 string HeaderFile(const AidlInterface& interface,
    798                   ClassNames class_type,
    799                   bool use_os_sep) {
    800   string file_path = interface.GetPackage();
    801   for (char& c: file_path) {
    802     if (c == '.') {
    803       c = (use_os_sep) ? OS_PATH_SEPARATOR : '/';
    804     }
    805   }
    806   if (!file_path.empty()) {
    807     file_path += (use_os_sep) ? OS_PATH_SEPARATOR : '/';
    808   }
    809   file_path += ClassName(interface, class_type);
    810   file_path += ".h";
    811 
    812   return file_path;
    813 }
    814 
    815 bool GenerateCpp(const CppOptions& options,
    816                  const TypeNamespace& types,
    817                  const AidlInterface& interface,
    818                  const IoDelegate& io_delegate) {
    819   auto interface_src = BuildInterfaceSource(types, interface);
    820   auto client_src = BuildClientSource(types, interface);
    821   auto server_src = BuildServerSource(types, interface);
    822 
    823   if (!interface_src || !client_src || !server_src) {
    824     return false;
    825   }
    826 
    827   if (!io_delegate.CreatedNestedDirs(options.OutputHeaderDir(),
    828                                      interface.GetSplitPackage())) {
    829     LOG(ERROR) << "Failed to create directory structure for headers.";
    830     return false;
    831   }
    832 
    833   if (!WriteHeader(options, types, interface, io_delegate,
    834                    ClassNames::INTERFACE) ||
    835       !WriteHeader(options, types, interface, io_delegate,
    836                    ClassNames::CLIENT) ||
    837       !WriteHeader(options, types, interface, io_delegate,
    838                    ClassNames::SERVER)) {
    839     return false;
    840   }
    841 
    842   unique_ptr<CodeWriter> writer = io_delegate.GetCodeWriter(
    843       options.OutputCppFilePath());
    844   interface_src->Write(writer.get());
    845   client_src->Write(writer.get());
    846   server_src->Write(writer.get());
    847 
    848   const bool success = writer->Close();
    849   if (!success) {
    850     io_delegate.RemovePath(options.OutputCppFilePath());
    851   }
    852 
    853   return success;
    854 }
    855 
    856 }  // namespace cpp
    857 }  // namespace aidl
    858 }  // namespace android
    859