1eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley/* 2eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * Copyright (C) 2015, The Android Open Source Project 3eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * 4eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * Licensed under the Apache License, Version 2.0 (the "License"); 5eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * you may not use this file except in compliance with the License. 6eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * You may obtain a copy of the License at 7eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * 8eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * http://www.apache.org/licenses/LICENSE-2.0 9eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * 10eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * Unless required by applicable law or agreed to in writing, software 11eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * distributed under the License is distributed on an "AS IS" BASIS, 12eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * See the License for the specific language governing permissions and 14eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley * limitations under the License. 15eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley */ 16eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley 17eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley#include "generate_cpp.h" 189a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 19082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin#include <cctype> 20ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley#include <cstring> 219a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley#include <memory> 22082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin#include <random> 23ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin#include <set> 249a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley#include <string> 259a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 260a62067f35e957493bc37c4b42dfdcfc16353831Elliott Hughes#include <android-base/stringprintf.h> 27e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wiley 28a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin#include "aidl_language.h" 299a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley#include "ast_cpp.h" 309a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley#include "code_writer.h" 31eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley#include "logging.h" 32054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley#include "os.h" 33eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley 34e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wileyusing android::base::StringPrintf; 359a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wileyusing std::string; 36082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlinusing std::unique_ptr; 37a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlinusing std::vector; 38ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlinusing std::set; 399a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 40eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wileynamespace android { 41eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wileynamespace aidl { 42f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wileynamespace cpp { 43a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlinnamespace internals { 440c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wileynamespace { 4536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 46b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kAndroidStatusVarName[] = "_aidl_ret_status"; 47b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kCodeVarName[] = "_aidl_code"; 48b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kFlagsVarName[] = "_aidl_flags"; 49b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kDataVarName[] = "_aidl_data"; 50b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kErrorLabel[] = "_aidl_error"; 51b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kImplVarName[] = "_aidl_impl"; 52b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kReplyVarName[] = "_aidl_reply"; 53ad3392747003a30928da6cd206e41f66398c2062Christopher Wileyconst char kReturnVarName[] = "_aidl_return"; 54b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kStatusVarName[] = "_aidl_status"; 55b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kAndroidParcelLiteral[] = "::android::Parcel"; 56b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kAndroidStatusLiteral[] = "::android::status_t"; 57b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kAndroidStatusOk[] = "::android::OK"; 58b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlinconst char kBinderStatusLiteral[] = "::android::binder::Status"; 590c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wileyconst char kIBinderHeader[] = "binder/IBinder.h"; 600c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wileyconst char kIInterfaceHeader[] = "binder/IInterface.h"; 61ad3392747003a30928da6cd206e41f66398c2062Christopher Wileyconst char kParcelHeader[] = "binder/Parcel.h"; 62433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wileyconst char kStatusHeader[] = "binder/Status.h"; 6369b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wileyconst char kString16Header[] = "utils/String16.h"; 64389781f56bb6b4363e9eb03acf915ba297f607d5Casey Dahlinconst char kStrongPointerHeader[] = "utils/StrongPointer.h"; 65082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin 660eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wileyunique_ptr<AstNode> BreakOnStatusNotOk() { 670eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley IfStatement* ret = new IfStatement(new Comparison( 68b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(kAndroidStatusVarName), "!=", 69b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(kAndroidStatusOk))); 700eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley ret->OnTrue()->AddLiteral("break"); 710eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley return unique_ptr<AstNode>(ret); 720eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley} 730eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley 74433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wileyunique_ptr<AstNode> GotoErrorOnBadStatus() { 75433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley IfStatement* ret = new IfStatement(new Comparison( 76b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(kAndroidStatusVarName), "!=", 77b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(kAndroidStatusOk))); 78b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ret->OnTrue()->AddLiteral(StringPrintf("goto %s", kErrorLabel)); 79433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley return unique_ptr<AstNode>(ret); 80433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley} 81433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley 82433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley 830eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wileyunique_ptr<AstNode> ReturnOnStatusNotOk() { 840eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley IfStatement* ret = new IfStatement(new Comparison( 85b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(kAndroidStatusVarName), "!=", 86b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(kAndroidStatusOk))); 87b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ret->OnTrue()->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName)); 880eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley return unique_ptr<AstNode>(ret); 890eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley} 900eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley 910c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wileystring UpperCase(const std::string& s) { 920c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley string result = s; 930c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley for (char& c : result) 940c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley c = toupper(c); 950c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley return result; 96a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin} 97a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin 98ad3392747003a30928da6cd206e41f66398c2062Christopher Wileystring BuildVarName(const AidlArgument& a) { 99ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley string prefix = "out_"; 100ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (a.GetDirection() & AidlArgument::IN_DIR) { 101ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley prefix = "in_"; 102e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wiley } 103ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley return prefix + a.GetName(); 104082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin} 105082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin 106ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher WileyArgList BuildArgList(const TypeNamespace& types, 107ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley const AidlMethod& method, 108ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley bool for_declaration) { 109ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Build up the argument list for the server method call. 110ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley vector<string> method_arguments; 111ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley for (const unique_ptr<AidlArgument>& a : method.GetArguments()) { 112ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley string literal; 113ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (for_declaration) { 114ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Method declarations need types, pointers to out params, and variable 115ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // names that match the .aidl specification. 116a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* type = a->GetType().GetLanguageType<Type>(); 117ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin 118a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin literal = type->CppType(); 119b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 120b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley if (a->IsOut()) { 121b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley literal = literal + "*"; 122b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley } else { 123b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley // We pass in parameters that are not primitives by const reference. 124b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley // Arrays of primitives are not primitives. 125b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley if (!type->IsCppPrimitive() || a->GetType().IsArray()) { 126b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley literal = "const " + literal + "&"; 127b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley } 128b8e49a407e8648afb28ca9bad4bf8434224f0b18Christopher Wiley } 129b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 130b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin literal += " " + a->GetName(); 131ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } else { 132ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (a->IsOut()) { literal = "&"; } 133ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley literal += BuildVarName(*a); 134ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 135ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley method_arguments.push_back(literal); 136ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 137ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 138a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* return_type = method.GetType().GetLanguageType<Type>(); 139ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin 140ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (return_type != types.VoidType()) { 141ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley string literal; 142ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (for_declaration) { 143ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley literal = StringPrintf( 144a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin "%s* %s", return_type->CppType().c_str(), 145b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin kReturnVarName); 146ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } else { 147ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley literal = string{"&"} + kReturnVarName; 148ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 149ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley method_arguments.push_back(literal); 1500c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley } 1510c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 152ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley return ArgList(method_arguments); 153ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley} 1540c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 155ad3392747003a30928da6cd206e41f66398c2062Christopher Wileyunique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method, 156ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley const TypeNamespace& types, 157ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley bool for_interface) { 1580c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley uint32_t modifiers = 0; 1590c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley if (for_interface) { 1600c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley modifiers |= MethodDecl::IS_VIRTUAL; 1610c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley modifiers |= MethodDecl::IS_PURE_VIRTUAL; 1620c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley } else { 1630c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley modifiers |= MethodDecl::IS_OVERRIDE; 1640c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley } 1650c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 1660c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley return unique_ptr<Declaration>{ 167433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley new MethodDecl{kBinderStatusLiteral, 168f4a9311fa018c78a7b30a73bd8ebbaa33c701ae4Casey Dahlin method.GetName(), 169ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley BuildArgList(types, method, true /* for method decl */), 1700c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley modifiers}}; 1710c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley} 1720c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 173b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wileyunique_ptr<CppNamespace> NestInNamespaces( 174b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley vector<unique_ptr<Declaration>> decls, 175b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley const vector<string>& package) { 176b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley if (package.empty()) { 177b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley // We should also be checking this before we get this far, but do it again 178b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley // for the sake of unit tests and meaningful errors. 179b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley LOG(FATAL) << "C++ generation requires a package declaration " 180b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley "for namespacing"; 181b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley } 182b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley auto it = package.crbegin(); // Iterate over the namespaces inner to outer 183b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley unique_ptr<CppNamespace> inner{new CppNamespace{*it, std::move(decls)}}; 184b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley ++it; 185b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley for (; it != package.crend(); ++it) { 186b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley inner.reset(new CppNamespace{*it, std::move(inner)}); 187b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley } 188b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley return inner; 1890c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley} 1900c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 191b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wileyunique_ptr<CppNamespace> NestInNamespaces(unique_ptr<Declaration> decl, 192b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley const vector<string>& package) { 193b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley vector<unique_ptr<Declaration>> decls; 194b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley decls.push_back(std::move(decl)); 195b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley return NestInNamespaces(std::move(decls), package); 19636570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley} 19736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 198ad3392747003a30928da6cd206e41f66398c2062Christopher Wileybool DeclareLocalVariable(const TypeNamespace& types, const AidlArgument& a, 199ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley StatementBlock* b) { 200a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* cpp_type = a.GetType().GetLanguageType<Type>(); 201ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (!cpp_type) { return false; } 202ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 203a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin string type = cpp_type->CppType(); 204b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 205b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin b->AddLiteral(type + " " + BuildVarName(a)); 206ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley return true; 207ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley} 208ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 2091ae2bc56d20fe0e19262f2721abc338662fa6e30Casey Dahlinstring ClassName(const AidlInterface& interface, ClassNames type) { 210fb7da2e62fe66b0a57ffbb0304f5884024a68f1cCasey Dahlin string c_name = interface.GetName(); 2110c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 2120c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley if (c_name.length() >= 2 && c_name[0] == 'I' && isupper(c_name[1])) 2130c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley c_name = c_name.substr(1); 2140c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 2150c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley switch (type) { 2160c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley case ClassNames::CLIENT: 2170c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley c_name = "Bp" + c_name; 2180c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley break; 2190c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley case ClassNames::SERVER: 2200c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley c_name = "Bn" + c_name; 2210c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley break; 2220c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley case ClassNames::INTERFACE: 2230c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley c_name = "I" + c_name; 2240c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley break; 2250c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley case ClassNames::BASE: 2260c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley break; 2270c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley } 2280c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley return c_name; 2290c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley} 2300c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 2313bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wileystring BuildHeaderGuard(const AidlInterface& interface, 2323bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley ClassNames header_type) { 2333bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley string class_name = ClassName(interface, header_type); 2343bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley for (size_t i = 1; i < class_name.size(); ++i) { 2353bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley if (isupper(class_name[i])) { 2363bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley class_name.insert(i, "_"); 2373bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley ++i; 2383bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley } 2393bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley } 2403bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley string ret = StringPrintf("AIDL_GENERATED_%s_%s_H_", 2413bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley interface.GetPackage().c_str(), 2423bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley class_name.c_str()); 2433bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley for (char& c : ret) { 2443bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley if (c == '.') { 2453bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley c = '_'; 2463bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley } 2473bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley c = toupper(c); 2483bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley } 2493bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley return ret; 2503bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley} 25136570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 25236570f4779a413ebef9302d1563fd92917ec2e42Christopher Wileyunique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types, 25336570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley const AidlInterface& interface, 25436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley const AidlMethod& method) { 25536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley const string i_name = ClassName(interface, ClassNames::INTERFACE); 25636570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley const string bp_name = ClassName(interface, ClassNames::CLIENT); 25736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley unique_ptr<MethodImpl> ret{new MethodImpl{ 258433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley kBinderStatusLiteral, bp_name, method.GetName(), 25936570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley ArgList{BuildArgList(types, method, true /* for method decl */)}}}; 26036570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley StatementBlock* b = ret->GetStatementBlock(); 26136570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 26236570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // Declare parcels to hold our query and the response. 263b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kDataVarName)); 2641227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley // Even if we're oneway, the transact method still takes a parcel. 265b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kReplyVarName)); 2660dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin 267433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // Declare the status_t variable we need for error handling. 2681095712f27931cb64d398d77201036cdcef0a296Christopher Wiley b->AddLiteral(StringPrintf("%s %s = %s", kAndroidStatusLiteral, 2691095712f27931cb64d398d77201036cdcef0a296Christopher Wiley kAndroidStatusVarName, 2701095712f27931cb64d398d77201036cdcef0a296Christopher Wiley kAndroidStatusOk)); 271433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // We unconditionally return a Status object. 272433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddLiteral(StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName)); 27336570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 2748993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley // Add the name of the interface we're hoping to call. 2758993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley b->AddStatement(new Assignment( 276b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 277b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new MethodCall(StringPrintf("%s.writeInterfaceToken", 278b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kDataVarName), 279b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin "getInterfaceDescriptor()"))); 280433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 2818993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley 28274b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley for (const auto& a: method.GetArguments()) { 283a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* type = a->GetType().GetLanguageType<Type>(); 28436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley string var_name = ((a->IsOut()) ? "*" : "") + a->GetName(); 285389781f56bb6b4363e9eb03acf915ba297f607d5Casey Dahlin var_name = type->WriteCast(var_name); 28674b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley 28774b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley if (a->IsIn()) { 28874b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // Serialization looks roughly like: 28974b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // _aidl_ret_status = _aidl_data.WriteInt32(in_param_name); 29074b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // if (_aidl_ret_status != ::android::OK) { goto error; } 29174b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley const string& method = type->WriteToParcelMethod(); 29274b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(new Assignment( 29374b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley kAndroidStatusVarName, 29474b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()), 29574b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley ArgList(var_name)))); 29674b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 29774b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley } else if (a->IsOut() && a->GetType().IsArray()) { 29874b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // Special case, the length of the out array is written into the parcel. 29974b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name); 30074b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // if (_aidl_ret_status != ::android::OK) { goto error; } 30174b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(new Assignment( 30274b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley kAndroidStatusVarName, 30374b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName), 30474b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley ArgList(var_name)))); 30574b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 30674b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley } 30736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley } 30836570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 30936570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // Invoke the transaction on the remote binder and confirm status. 31036570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley string transaction_code = StringPrintf( 31136570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley "%s::%s", i_name.c_str(), UpperCase(method.GetName()).c_str()); 3120dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin 313b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin vector<string> args = {transaction_code, kDataVarName, 314b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("&%s", kReplyVarName)}; 3150dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin 3160dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin if (interface.IsOneway() || method.IsOneway()) { 317b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin args.push_back("::android::IBinder::FLAG_ONEWAY"); 3180dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin } 3190dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin 32036570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley b->AddStatement(new Assignment( 321b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 32236570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley new MethodCall("remote()->transact", 3230dd08af9e6145fb746e96e7ecc5e4c2096de3a6eCasey Dahlin ArgList(args)))); 324433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 32536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 3261227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley if (!interface.IsOneway() && !method.IsOneway()) { 3271227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley // Strip off the exception header and fail if we see a remote exception. 328b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 329b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // if (_aidl_ret_status != ::android::OK) { goto error; } 330b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // if (!_aidl_status.isOk()) { return _aidl_ret_status; } 331433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(new Assignment( 332b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 333b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("%s.readFromParcel(%s)", kStatusVarName, kReplyVarName))); 334433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 3351227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley IfStatement* exception_check = new IfStatement( 336433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName))); 3371227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley b->AddStatement(exception_check); 338433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley exception_check->OnTrue()->AddLiteral( 339433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley StringPrintf("return %s", kStatusVarName)); 3401227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley } 3411227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley 3421227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley // Type checking should guarantee that nothing below emits code until "return 3431227d6135418a6a876666adcf4f8d9b498f17647Christopher Wiley // status" if we are a oneway method, so no more fear of accessing reply. 3442aaeda8b140de83f2cb2d51405ea27ccf1eefc13Christopher Wiley 34536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // If the method is expected to return something, read it first by convention. 346a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* return_type = method.GetType().GetLanguageType<Type>(); 34736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley if (return_type != types.VoidType()) { 348f05cc26630828c848e46ea0e584dbdd2541ea723Chih-Hung Hsieh const string& method_call = return_type->ReadFromParcelMethod(); 34936570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley b->AddStatement(new Assignment( 350b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 351b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new MethodCall(StringPrintf("%s.%s", kReplyVarName, 352b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin method_call.c_str()), 353b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ArgList(kReturnVarName)))); 354433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 35536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley } 35636570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 35736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley for (const AidlArgument* a : method.GetOutArguments()) { 35836570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // Deserialization looks roughly like: 359b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name); 360b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // if (_aidl_status != ::android::OK) { goto _aidl_error; } 361b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin string method = 362a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod(); 363b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 36436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley b->AddStatement(new Assignment( 365b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 366b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new MethodCall(StringPrintf("%s.%s", kReplyVarName, 367b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin method.c_str()), 368b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ArgList(a->GetName())))); 369433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(GotoErrorOnBadStatus()); 37036570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley } 37136570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 372433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // If we've gotten to here, one of two things is true: 373433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // 1) We've read some bad status_t 374433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // 2) We've only read status_t == OK and there was no exception in the 375433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // response. 376433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // In both cases, we're free to set Status from the status_t and return. 377b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin b->AddLiteral(StringPrintf("%s:\n", kErrorLabel), false /* no semicolon */); 378433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddLiteral( 379b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("%s.setFromStatusT(%s)", kStatusVarName, 380b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName)); 381433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddLiteral(StringPrintf("return %s", kStatusVarName)); 38236570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 38336570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley return unique_ptr<Declaration>(ret.release()); 38436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley} 38536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 38636570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley} // namespace 38736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 388e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wileyunique_ptr<Document> BuildClientSource(const TypeNamespace& types, 38936570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley const AidlInterface& interface) { 390054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley vector<string> include_list = { 391054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley HeaderFile(interface, ClassNames::CLIENT, false), 392054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley kParcelHeader 393054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley }; 39436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley vector<unique_ptr<Declaration>> file_decls; 39536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 39636570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // The constructor just passes the IBinder instance up to the super 39736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // class. 3981db03482145137749602c830a593494498f5be55Christopher Wiley const string i_name = ClassName(interface, ClassNames::INTERFACE); 39936570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley file_decls.push_back(unique_ptr<Declaration>{new ConstructorImpl{ 400054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley ClassName(interface, ClassNames::CLIENT), 401b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s", 402b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kImplVarName)}, 403b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin { "BpInterface<" + i_name + ">(" + kImplVarName + ")" }}}); 40436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 40536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // Clients define a method per transaction. 40636570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley for (const auto& method : interface.GetMethods()) { 40736570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley unique_ptr<Declaration> m = DefineClientTransaction( 40836570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley types, interface, *method); 40936570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley if (!m) { return nullptr; } 41036570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley file_decls.push_back(std::move(m)); 41136570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley } 41236570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley return unique_ptr<Document>{new CppSource{ 41336570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley include_list, 414b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley NestInNamespaces(std::move(file_decls), interface.GetSplitPackage())}}; 4159a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley} 4169a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 417ad3392747003a30928da6cd206e41f66398c2062Christopher Wileynamespace { 418ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 419ad3392747003a30928da6cd206e41f66398c2062Christopher Wileybool HandleServerTransaction(const TypeNamespace& types, 420ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley const AidlMethod& method, 421ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley StatementBlock* b) { 422ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Declare all the parameters now. In the common case, we expect no errors 423ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // in serialization. 424ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley for (const unique_ptr<AidlArgument>& a : method.GetArguments()) { 425ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (!DeclareLocalVariable(types, *a, b)) { return false; } 426ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 427ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 428ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Declare a variable to hold the return value. 429a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* return_type = method.GetType().GetLanguageType<Type>(); 430ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (return_type != types.VoidType()) { 431ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley b->AddLiteral(StringPrintf( 432a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin "%s %s", return_type->CppType().c_str(), 433b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin kReturnVarName)); 434ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 435ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 4368993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley // Check that the client is calling the correct interface. 4378993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley IfStatement* interface_check = new IfStatement( 438b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new MethodCall(StringPrintf("%s.checkInterface", 439b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kDataVarName), "this"), 4408993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley true /* invert the check */); 4418993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley b->AddStatement(interface_check); 4428993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley interface_check->OnTrue()->AddStatement( 443b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new Assignment(kAndroidStatusVarName, "::android::BAD_TYPE")); 4448993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley interface_check->OnTrue()->AddLiteral("break"); 4458993cb5f297f9e329470d75f02a7b3e3a4bc64a5Christopher Wiley 446ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Deserialize each "in" parameter to the transaction. 44774b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley for (const auto& a: method.GetArguments()) { 448ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Deserialization looks roughly like: 449b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name); 450b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // if (_aidl_ret_status != ::android::OK) { break; } 451a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* type = a->GetType().GetLanguageType<Type>(); 452f05cc26630828c848e46ea0e584dbdd2541ea723Chih-Hung Hsieh const string& readMethod = type->ReadFromParcelMethod(); 453b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 45474b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley if (a->IsIn()) { 45574b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(new Assignment{ 45674b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley kAndroidStatusVarName, 45774b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley new MethodCall{string(kDataVarName) + "." + readMethod, 45874b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley "&" + BuildVarName(*a)}}); 45974b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(BreakOnStatusNotOk()); 46074b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley } else if (a->IsOut() && a->GetType().IsArray()) { 46174b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // Special case, the length of the out array is written into the parcel. 46274b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name); 46374b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley // if (_aidl_ret_status != ::android::OK) { break; } 46474b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(new Assignment{ 46574b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley kAndroidStatusVarName, 46674b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley new MethodCall{string(kDataVarName) + ".resizeOutVector", 46774b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley "&" + BuildVarName(*a)}}); 46874b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley b->AddStatement(BreakOnStatusNotOk()); 46974b7bf1043d1905e6f999f7c47920319029453c0Christopher Wiley } 470ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 471ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 472ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Call the actual method. This is implemented by the subclass. 473433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley vector<unique_ptr<AstNode>> status_args; 474433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley status_args.emplace_back(new MethodCall( 475ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley method.GetName(), 476433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley BuildArgList(types, method, false /* not for method decl */))); 477433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(new Statement(new MethodCall( 478433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName), 479433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley ArgList(std::move(status_args))))); 480ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 481433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // Write exceptions during transaction handling to parcel. 482433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley if (!method.IsOneway()) { 483433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(new Assignment( 484b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 485b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("%s.writeToParcel(%s)", kStatusVarName, kReplyVarName))); 486433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(BreakOnStatusNotOk()); 487433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley IfStatement* exception_check = new IfStatement( 488433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName))); 489433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley b->AddStatement(exception_check); 490433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley exception_check->OnTrue()->AddLiteral("break"); 491433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley } 492b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 49336570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley // If we have a return value, write it first. 49436570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley if (return_type != types.VoidType()) { 4952aaeda8b140de83f2cb2d51405ea27ccf1eefc13Christopher Wiley string writeMethod = 496b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin string(kReplyVarName) + "->" + 497a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin return_type->WriteToParcelMethod(); 49836570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley b->AddStatement(new Assignment{ 499b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, new MethodCall{writeMethod, 500389781f56bb6b4363e9eb03acf915ba297f607d5Casey Dahlin ArgList{return_type->WriteCast(kReturnVarName)}}}); 5010eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley b->AddStatement(BreakOnStatusNotOk()); 50236570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley } 50336570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley 504ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Write each out parameter to the reply parcel. 505ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley for (const AidlArgument* a : method.GetOutArguments()) { 506ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Serialization looks roughly like: 507b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // _aidl_ret_status = data.WriteInt32(out_param_name); 508b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin // if (_aidl_ret_status != ::android::OK) { break; } 509a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* type = a->GetType().GetLanguageType<Type>(); 510f05cc26630828c848e46ea0e584dbdd2541ea723Chih-Hung Hsieh const string& writeMethod = type->WriteToParcelMethod(); 511b0966619850093e117104dc34d8a6ae4c56ea3ffCasey Dahlin 512ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley b->AddStatement(new Assignment{ 513b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 514b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new MethodCall{string(kReplyVarName) + "->" + writeMethod, 515389781f56bb6b4363e9eb03acf915ba297f607d5Casey Dahlin type->WriteCast(BuildVarName(*a))}}); 5160eb903eff2376941ad7e947bd5d3a32e15d89f69Christopher Wiley b->AddStatement(BreakOnStatusNotOk()); 517ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 518ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 519ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley return true; 520ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley} 521ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 522ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley} // namespace 523ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 524e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wileyunique_ptr<Document> BuildServerSource(const TypeNamespace& types, 525054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const AidlInterface& interface) { 526054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const string bn_name = ClassName(interface, ClassNames::SERVER); 527054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley vector<string> include_list{ 528054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley HeaderFile(interface, ClassNames::SERVER, false), 529054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley kParcelHeader 530054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley }; 531ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley unique_ptr<MethodImpl> on_transact{new MethodImpl{ 532ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley kAndroidStatusLiteral, bn_name, "onTransact", 533b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ArgList{{StringPrintf("uint32_t %s", kCodeVarName), 534b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("const %s& %s", kAndroidParcelLiteral, 535b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kDataVarName), 536b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName), 537b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("uint32_t %s", kFlagsVarName)}} 53836570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley }}; 539ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 540433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // Declare the status_t variable 54105f4f890cad7b2a510e8e1f80fa5884db1bd8383Christopher Wiley on_transact->GetStatementBlock()->AddLiteral( 5421095712f27931cb64d398d77201036cdcef0a296Christopher Wiley StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName, 5431095712f27931cb64d398d77201036cdcef0a296Christopher Wiley kAndroidStatusOk)); 54405f4f890cad7b2a510e8e1f80fa5884db1bd8383Christopher Wiley 545ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Add the all important switch statement, but retain a pointer to it. 546b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin SwitchStatement* s = new SwitchStatement{kCodeVarName}; 547f9688b04c9e34063e8b2dffab4827e02f4f104faChristopher Wiley on_transact->GetStatementBlock()->AddStatement(s); 548ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 549ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // The switch statement has a case statement for each transaction code. 550054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley for (const auto& method : interface.GetMethods()) { 551ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley StatementBlock* b = s->AddCase("Call::" + UpperCase(method->GetName())); 552ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (!b) { return nullptr; } 553ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 554ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley if (!HandleServerTransaction(types, *method, b)) { return nullptr; } 555ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley } 556ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 557ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // The switch statement has a default case which defers to the super class. 558ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // The superclass handles a few pre-defined transactions. 559ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley StatementBlock* b = s->AddCase(""); 560b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin b->AddLiteral(StringPrintf( 561b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin "%s = ::android::BBinder::onTransact(%s, %s, " 562b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin "%s, %s)", kAndroidStatusVarName, kCodeVarName, 563b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kDataVarName, kReplyVarName, kFlagsVarName)); 564ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 565433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley // If we saw a null reference, we can map that to an appropriate exception. 566433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley IfStatement* null_check = new IfStatement( 567b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin new LiteralExpression(string(kAndroidStatusVarName) + 568b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin " == ::android::UNEXPECTED_NULL")); 569433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley on_transact->GetStatementBlock()->AddStatement(null_check); 570433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley null_check->OnTrue()->AddStatement(new Assignment( 571b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kAndroidStatusVarName, 572433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley StringPrintf("%s::fromExceptionCode(%s::EX_NULL_POINTER)" 573b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ".writeToParcel(%s)", 574b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kBinderStatusLiteral, kBinderStatusLiteral, 575b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kReplyVarName))); 576433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley 577ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley // Finally, the server's onTransact method just returns a status code. 578b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin on_transact->GetStatementBlock()->AddLiteral( 579b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("return %s", kAndroidStatusVarName)); 580ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley 581ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley return unique_ptr<Document>{new CppSource{ 582ad3392747003a30928da6cd206e41f66398c2062Christopher Wiley include_list, 583b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley NestInNamespaces(std::move(on_transact), interface.GetSplitPackage())}}; 5849a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley} 5859a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 586f59c49950aea9d5d0111a4558b58c336c9091ea6Christopher Wileyunique_ptr<Document> BuildInterfaceSource(const TypeNamespace& /* types */, 587054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const AidlInterface& interface) { 588054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley vector<string> include_list{ 589054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley HeaderFile(interface, ClassNames::INTERFACE, false), 590054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley HeaderFile(interface, ClassNames::CLIENT, false), 591054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley }; 592054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 593054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley string fq_name = ClassName(interface, ClassNames::INTERFACE); 594054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (!interface.GetPackage().empty()) { 595054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley fq_name = interface.GetPackage() + "." + fq_name; 5961dd458d3e3647823acb9554f8ae17631d597a1ecChristopher Wiley } 5971dd458d3e3647823acb9554f8ae17631d597a1ecChristopher Wiley 59869b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley vector<unique_ptr<Declaration>> decls; 59969b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley 60011a9d79a1189bbfa5b64a77b32f1a947ad91f0ddChristopher Wiley unique_ptr<MacroDecl> meta_if{new MacroDecl{ 6011dd458d3e3647823acb9554f8ae17631d597a1ecChristopher Wiley "IMPLEMENT_META_INTERFACE", 602054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley ArgList{vector<string>{ClassName(interface, ClassNames::BASE), 603ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley '"' + fq_name + '"'}}}}; 60469b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley decls.push_back(std::move(meta_if)); 60569b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley 60669b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley for (const auto& constant: interface.GetStringConstants()) { 60769b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley unique_ptr<MethodImpl> getter(new MethodImpl( 60869b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley "const ::android::String16&", 60969b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley ClassName(interface, ClassNames::INTERFACE), 61069b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley constant->GetName(), 61169b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley {})); 61269b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley getter->GetStatementBlock()->AddLiteral( 61369b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley StringPrintf("static const ::android::String16 value(%s)", 61469b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley constant->GetValue().c_str())); 61569b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley getter->GetStatementBlock()->AddLiteral("return value"); 61669b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley decls.push_back(std::move(getter)); 61769b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley } 6181dd458d3e3647823acb9554f8ae17631d597a1ecChristopher Wiley 6191dd458d3e3647823acb9554f8ae17631d597a1ecChristopher Wiley return unique_ptr<Document>{new CppSource{ 6201dd458d3e3647823acb9554f8ae17631d597a1ecChristopher Wiley include_list, 62169b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley NestInNamespaces(std::move(decls), interface.GetSplitPackage())}}; 6229a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley} 6239a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 624e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wileyunique_ptr<Document> BuildClientHeader(const TypeNamespace& types, 6253bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley const AidlInterface& interface) { 6263bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley const string i_name = ClassName(interface, ClassNames::INTERFACE); 6273bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley const string bp_name = ClassName(interface, ClassNames::CLIENT); 628082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin 629b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley unique_ptr<ConstructorDecl> constructor{new ConstructorDecl{ 630b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley bp_name, 631b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s", 632b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kImplVarName)}, 633b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley ConstructorDecl::IS_EXPLICIT 634b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley }}; 635b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley unique_ptr<ConstructorDecl> destructor{new ConstructorDecl{ 636b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley "~" + bp_name, 637b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley ArgList{}, 638b23149dbc77744864b78edeb9f9cbb2f94f8c06dChristopher Wiley ConstructorDecl::IS_VIRTUAL | ConstructorDecl::IS_DEFAULT}}; 639a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin 640f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley vector<unique_ptr<Declaration>> publics; 641a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin publics.push_back(std::move(constructor)); 642a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin publics.push_back(std::move(destructor)); 643082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin 6443bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley for (const auto& method: interface.GetMethods()) { 64536570f4779a413ebef9302d1563fd92917ec2e42Christopher Wiley publics.push_back(BuildMethodDecl(*method, types, false)); 646a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin } 647a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin 648f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley unique_ptr<ClassDecl> bp_class{ 649f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley new ClassDecl{bp_name, 650b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin "::android::BpInterface<" + i_name + ">", 651f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley std::move(publics), 652f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley {} 653a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin }}; 654a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin 6550c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley return unique_ptr<Document>{new CppHeader{ 6563bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley BuildHeaderGuard(interface, ClassNames::CLIENT), 6570c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley {kIBinderHeader, 6580c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley kIInterfaceHeader, 6590c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley "utils/Errors.h", 660054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley HeaderFile(interface, ClassNames::INTERFACE, false)}, 661b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}}; 662a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin} 663a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin 664f59c49950aea9d5d0111a4558b58c336c9091ea6Christopher Wileyunique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */, 665fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley const AidlInterface& interface) { 666fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley const string i_name = ClassName(interface, ClassNames::INTERFACE); 667fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley const string bn_name = ClassName(interface, ClassNames::SERVER); 668082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin 669fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley unique_ptr<Declaration> on_transact{new MethodDecl{ 670ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley kAndroidStatusLiteral, "onTransact", 671b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin ArgList{{StringPrintf("uint32_t %s", kCodeVarName), 672b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("const %s& %s", kAndroidParcelLiteral, 673b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin kDataVarName), 674b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName), 675b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin StringPrintf("uint32_t %s = 0", kFlagsVarName)}}, 676fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley MethodDecl::IS_OVERRIDE 677fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley }}; 678082f1d172dbc9de990a04c26b55972faf812771bCasey Dahlin 679f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley std::vector<unique_ptr<Declaration>> publics; 680b7d0f7f4bb08171e025659d17cd3bb57b35b739aCasey Dahlin publics.push_back(std::move(on_transact)); 681b7d0f7f4bb08171e025659d17cd3bb57b35b739aCasey Dahlin 682f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley unique_ptr<ClassDecl> bn_class{ 683f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley new ClassDecl{bn_name, 684b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin "::android::BnInterface<" + i_name + ">", 685f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley std::move(publics), 686f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley {} 687b7d0f7f4bb08171e025659d17cd3bb57b35b739aCasey Dahlin }}; 688b7d0f7f4bb08171e025659d17cd3bb57b35b739aCasey Dahlin 6890c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley return unique_ptr<Document>{new CppHeader{ 690fd51d60f486f1ad514e6f24744ebffab7a3d89bdChristopher Wiley BuildHeaderGuard(interface, ClassNames::SERVER), 6910c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley {"binder/IInterface.h", 692054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley HeaderFile(interface, ClassNames::INTERFACE, false)}, 693b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}}; 6949a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley} 6959a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 696e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wileyunique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types, 6973bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley const AidlInterface& interface) { 698389781f56bb6b4363e9eb03acf915ba297f607d5Casey Dahlin set<string> includes = { kIBinderHeader, kIInterfaceHeader, 699433c8bbdfa1ee6db10b7f08d3c50eafd49ad2687Christopher Wiley kStatusHeader, kStrongPointerHeader }; 700ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin 701ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin for (const auto& method : interface.GetMethods()) { 702ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin for (const auto& argument : method->GetArguments()) { 703a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* type = argument->GetType().GetLanguageType<Type>(); 704a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin type->GetHeaders(&includes); 705ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin } 706ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin 707a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin const Type* return_type = method->GetType().GetLanguageType<Type>(); 708a2f77c40fb6287895e2030055c0104eac0a1f73aCasey Dahlin return_type->GetHeaders(&includes); 709ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin } 710ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin 7110c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley unique_ptr<ClassDecl> if_class{ 7123bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley new ClassDecl{ClassName(interface, ClassNames::INTERFACE), 713b8d9e8898c34da45027e56be88d5c9238ea88203Casey Dahlin "::android::IInterface"}}; 71411a9d79a1189bbfa5b64a77b32f1a947ad91f0ddChristopher Wiley if_class->AddPublic(unique_ptr<Declaration>{new MacroDecl{ 715ade4b45d8d9e922aca70d0995f2fb8a170de838bChristopher Wiley "DECLARE_META_INTERFACE", 7163bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley ArgList{vector<string>{ClassName(interface, ClassNames::BASE)}}}}); 7170c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 718fd7dc03fdd1e0cd558df43a155ab1644cbe2b553Christopher Wiley unique_ptr<Enum> constant_enum{new Enum{"", "int32_t"}}; 719d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley for (const auto& constant : interface.GetIntConstants()) { 720fd7dc03fdd1e0cd558df43a155ab1644cbe2b553Christopher Wiley constant_enum->AddValue( 721fd7dc03fdd1e0cd558df43a155ab1644cbe2b553Christopher Wiley constant->GetName(), std::to_string(constant->GetValue())); 722fd7dc03fdd1e0cd558df43a155ab1644cbe2b553Christopher Wiley } 723fd7dc03fdd1e0cd558df43a155ab1644cbe2b553Christopher Wiley if (constant_enum->HasValues()) { 724fd7dc03fdd1e0cd558df43a155ab1644cbe2b553Christopher Wiley if_class->AddPublic(std::move(constant_enum)); 725d40e2fed2c19850d53f1620322ac5cbca2c0e245Casey Dahlin } 726d40e2fed2c19850d53f1620322ac5cbca2c0e245Casey Dahlin 72769b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley if (!interface.GetStringConstants().empty()) { 72869b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley includes.insert(kString16Header); 72969b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley } 73069b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley for (const auto& constant : interface.GetStringConstants()) { 73169b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley unique_ptr<MethodDecl> getter(new MethodDecl( 73269b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley "const ::android::String16&", constant->GetName(), 73369b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley {}, MethodDecl::IS_STATIC)); 73469b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley if_class->AddPublic(std::move(getter)); 73569b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley } 73669b44cf003bd5bda9dcd97a6fe872630c1b2818fChristopher Wiley 737d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley if (!interface.GetMethods().empty()) { 738d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley unique_ptr<Enum> call_enum{new Enum{"Call"}}; 739d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley for (const auto& method : interface.GetMethods()) { 740d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley // Each method gets an enum entry and pure virtual declaration. 741d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley if_class->AddPublic(BuildMethodDecl(*method, types, true)); 742d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley call_enum->AddValue( 743d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley UpperCase(method->GetName()), 744d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley StringPrintf("::android::IBinder::FIRST_CALL_TRANSACTION + %d", 745d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley method->GetId())); 746d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley } 747d6bdd8d7cfb0a96ccc826cbb005128f0f7ca3446Christopher Wiley if_class->AddPublic(std::move(call_enum)); 7480c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley } 7490c732dbae2e6b33cde9a266ea091e1459742f1f1Christopher Wiley 7503bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley return unique_ptr<Document>{new CppHeader{ 7513bb6bc1d481459cc9ec93b764d245040b78e6507Christopher Wiley BuildHeaderGuard(interface, ClassNames::INTERFACE), 752ce776cfc9560ee541464a23fb64ecd74e442b96fCasey Dahlin vector<string>(includes.begin(), includes.end()), 753b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley NestInNamespaces(std::move(if_class), interface.GetSplitPackage())}}; 7549a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley} 7559a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 756054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wileybool WriteHeader(const CppOptions& options, 757054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const TypeNamespace& types, 758054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const AidlInterface& interface, 759054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const IoDelegate& io_delegate, 760054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley ClassNames header_type) { 761054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley unique_ptr<Document> header; 762054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley switch (header_type) { 763054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley case ClassNames::INTERFACE: 764054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley header = BuildInterfaceHeader(types, interface); 765054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley break; 766054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley case ClassNames::CLIENT: 767054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley header = BuildClientHeader(types, interface); 768054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley break; 769054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley case ClassNames::SERVER: 770054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley header = BuildServerHeader(types, interface); 771054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley break; 772054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley default: 773054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley LOG(FATAL) << "aidl internal error"; 774054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 775054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (!header) { 776054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley LOG(ERROR) << "aidl internal error: Failed to generate header."; 7779a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley return false; 7789a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley } 779054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 7809d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley const string header_path = options.OutputHeaderDir() + OS_PATH_SEPARATOR + 7819d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley HeaderFile(interface, header_type); 7829d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley unique_ptr<CodeWriter> code_writer(io_delegate.GetCodeWriter(header_path)); 7839d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley header->Write(code_writer.get()); 784054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 7859d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley const bool success = code_writer->Close(); 7869d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley if (!success) { 7879d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley io_delegate.RemovePath(header_path); 7889d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley } 7899d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley 7909d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley return success; 7919a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley} 7929a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 793a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin} // namespace internals 794a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlin 795a834dd4650b3196893440ee49c7ff6b303b45a92Casey Dahlinusing namespace internals; 7969a8e1d9ad667faff9272e0e99b37a6aeba2d8d20Christopher Wiley 7973a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wileystring HeaderFile(const AidlInterface& interface, 7983a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley ClassNames class_type, 7993a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley bool use_os_sep) { 8003a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley string file_path = interface.GetPackage(); 8013a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley for (char& c: file_path) { 8023a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley if (c == '.') { 8033a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley c = (use_os_sep) ? OS_PATH_SEPARATOR : '/'; 8043a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley } 8053a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley } 8063a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley if (!file_path.empty()) { 8073a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley file_path += (use_os_sep) ? OS_PATH_SEPARATOR : '/'; 8083a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley } 8093a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley file_path += ClassName(interface, class_type); 8103a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley file_path += ".h"; 8113a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley 8123a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley return file_path; 8133a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley} 8143a9911cc8fd881effadbdf51e8f4cf721a1d9601Christopher Wiley 815e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wileybool GenerateCpp(const CppOptions& options, 816e3550c6679939d2bf5f35c540cd83198ab156fb7Christopher Wiley const TypeNamespace& types, 817054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const AidlInterface& interface, 818054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley const IoDelegate& io_delegate) { 819054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley auto interface_src = BuildInterfaceSource(types, interface); 820054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley auto client_src = BuildClientSource(types, interface); 821054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley auto server_src = BuildServerSource(types, interface); 822054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 823054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (!interface_src || !client_src || !server_src) { 824054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley return false; 825054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 826054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 827054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (!io_delegate.CreatedNestedDirs(options.OutputHeaderDir(), 828b656a3b1954bbe4b548a3c11274c833bbca35935Christopher Wiley interface.GetSplitPackage())) { 829054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley LOG(ERROR) << "Failed to create directory structure for headers."; 830054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley return false; 831054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 832054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 833054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley if (!WriteHeader(options, types, interface, io_delegate, 834054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley ClassNames::INTERFACE) || 835054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley !WriteHeader(options, types, interface, io_delegate, 836054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley ClassNames::CLIENT) || 837054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley !WriteHeader(options, types, interface, io_delegate, 838054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley ClassNames::SERVER)) { 839054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley return false; 840054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley } 841054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 842054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley unique_ptr<CodeWriter> writer = io_delegate.GetCodeWriter( 843054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley options.OutputCppFilePath()); 844054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley interface_src->Write(writer.get()); 845054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley client_src->Write(writer.get()); 846054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley server_src->Write(writer.get()); 847054afbd3037addb4f2e245ecbc36f31d3040f877Christopher Wiley 8489d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley const bool success = writer->Close(); 8499d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley if (!success) { 8509d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley io_delegate.RemovePath(options.OutputCppFilePath()); 8519d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley } 8529d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley 8539d6e0b29add607669e440085f1fc60cd434dc987Christopher Wiley return success; 854eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley} 855eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley 856f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley} // namespace cpp 857eb1acc1cf7dbf578d8ab2e596982c4c635aa9865Christopher Wiley} // namespace aidl 858f944e79bdaf92fffe9ea78314d3636e7e4de8c51Christopher Wiley} // namespace android 859