diff options
author | Luis Vidal <lvidal@cyngn.com> | 2016-06-22 17:17:52 -0700 |
---|---|---|
committer | Luis Vidal <lvidal@cyngn.com> | 2016-07-15 11:03:01 -0700 |
commit | edd2da9b5bf098db9505e84033ca45fda688fe7f (patch) | |
tree | 9501d504941cbd7c1f33a0395afe117e34f0a66a /tools/aidl | |
parent | df41276baeda099bdfe95c59af43c65dee2763eb (diff) | |
download | frameworks_base-edd2da9b5bf098db9505e84033ca45fda688fe7f.zip frameworks_base-edd2da9b5bf098db9505e84033ca45fda688fe7f.tar.gz frameworks_base-edd2da9b5bf098db9505e84033ca45fda688fe7f.tar.bz2 |
AIDL: Add option to generate No-Op methods
Add the option to generate a default (no-op) implementation
of an interface
Change-Id: I2631e93c8b85e056cf928e9592342dc4466f293e
Diffstat (limited to 'tools/aidl')
-rw-r--r-- | tools/aidl/aidl.cpp | 14 | ||||
-rw-r--r-- | tools/aidl/generate_java.cpp | 4 | ||||
-rw-r--r-- | tools/aidl/generate_java.h | 7 | ||||
-rw-r--r-- | tools/aidl/generate_java_binder.cpp | 93 | ||||
-rw-r--r-- | tools/aidl/options.cpp | 4 | ||||
-rw-r--r-- | tools/aidl/options.h | 1 |
6 files changed, 115 insertions, 8 deletions
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp index cd4fbe5..d37a946 100644 --- a/tools/aidl/aidl.cpp +++ b/tools/aidl/aidl.cpp @@ -345,6 +345,13 @@ gather_types(const char* filename, document_item_type* items) name, Type::GENERATED, false, false, false, filename, c->name.lineno); NAMES.Add(proxy); + + name = c->name.data; + name += ".NoOp"; + Type* noOp = new Type(c->package ? c->package : "", + name, Type::GENERATED, false, false, false, + filename, c->name.lineno); + NAMES.Add(noOp); } else if (items->item_type == INTERFACE_TYPE_RPC) { // for interfaces, also add the service base type, we don't @@ -1064,8 +1071,13 @@ compile_aidl(Options& options) // make sure the folders of the output file all exists check_outputFilePath(options.outputFileName); + int flags = 0; + if (options.generateNoOpMethods) { + flags |= GENERATE_NO_OP_CLASS; + } + err = generate_java(options.outputFileName, options.inputFileName.c_str(), - (interface_type*)mainDoc); + (interface_type*)mainDoc, flags); return err; } diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp index 9e57407..8817461 100644 --- a/tools/aidl/generate_java.cpp +++ b/tools/aidl/generate_java.cpp @@ -59,12 +59,12 @@ append(const char* a, const char* b) // ================================================= int generate_java(const string& filename, const string& originalSrc, - interface_type* iface) + interface_type* iface, int flags) { Class* cl; if (iface->document_item.item_type == INTERFACE_TYPE_BINDER) { - cl = generate_binder_interface_class(iface); + cl = generate_binder_interface_class(iface, flags); } else if (iface->document_item.item_type == INTERFACE_TYPE_RPC) { cl = generate_rpc_interface_class(iface); diff --git a/tools/aidl/generate_java.h b/tools/aidl/generate_java.h index 4bfcfeb..45b2703 100644 --- a/tools/aidl/generate_java.h +++ b/tools/aidl/generate_java.h @@ -9,9 +9,9 @@ using namespace std; int generate_java(const string& filename, const string& originalSrc, - interface_type* iface); + interface_type* iface, int flags); -Class* generate_binder_interface_class(const interface_type* iface); +Class* generate_binder_interface_class(const interface_type* iface, int flags); Class* generate_rpc_interface_class(const interface_type* iface); string gather_comments(extra_text_type* extra); @@ -29,5 +29,8 @@ private: int m_index; }; +//Set of flags that can be passed to generate_java +#define GENERATE_NO_OP_CLASS 1 << 0 + #endif // GENERATE_JAVA_H diff --git a/tools/aidl/generate_java_binder.cpp b/tools/aidl/generate_java_binder.cpp index 1b538ca..48ac027 100644 --- a/tools/aidl/generate_java_binder.cpp +++ b/tools/aidl/generate_java_binder.cpp @@ -194,6 +194,36 @@ ProxyClass::~ProxyClass() } // ================================================= +class DefaultNoOpClass : public Class { +public: + DefaultNoOpClass(Type* type, InterfaceType* interfaceType); + virtual ~DefaultNoOpClass(); +}; + +DefaultNoOpClass::DefaultNoOpClass(Type* type, InterfaceType* interfaceType) + :Class() +{ + this->comment = "/** No-Op implementation */"; + this->comment += "\n/** @hide */"; + this->modifiers = PUBLIC | STATIC; + this->what = Class::CLASS; + this->type = type; + this->interfaces.push_back(interfaceType); + + // IBinder asBinder() + Method* asBinder = new Method; + asBinder->modifiers = PUBLIC | OVERRIDE; + asBinder->returnType = IBINDER_TYPE; + asBinder->name = "asBinder"; + asBinder->statements = new StatementBlock; + asBinder->statements->Add(new ReturnStatement(NULL_VALUE)); + this->elements.push_back(asBinder); +} + +DefaultNoOpClass::~DefaultNoOpClass() { +} + +// ================================================= static void generate_new_array(Type* t, StatementBlock* addTo, Variable* v, Variable* parcel) @@ -245,10 +275,24 @@ generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v, } } +static bool +is_numeric_java_type(const char* str) { + static const char* KEYWORDS[] = { "int", "byte", "char", "float", "double", + "short", "long", NULL }; + const char** k = KEYWORDS; + while (*k) { + if (0 == strcmp(str, *k)) { + return true; + } + k++; + } + return false; +} static void generate_method(const method_type* method, Class* interface, - StubClass* stubClass, ProxyClass* proxyClass, int index) + StubClass* stubClass, ProxyClass* proxyClass, DefaultNoOpClass* noOpClass, + int index) { arg_type* arg; int i; @@ -294,6 +338,39 @@ generate_method(const method_type* method, Class* interface, interface->elements.push_back(decl); + // == the no-op method =================================================== + if (noOpClass != NULL) { + Method* noOpMethod = new Method; + noOpMethod->comment = gather_comments(method->comments_token->extra); + noOpMethod->modifiers = OVERRIDE | PUBLIC; + noOpMethod->returnType = NAMES.Search(method->type.type.data); + noOpMethod->returnTypeDimension = method->type.dimension; + noOpMethod->name = method->name.data; + noOpMethod->statements = new StatementBlock; + + arg = method->args; + while (arg != NULL) { + noOpMethod->parameters.push_back(new Variable( + NAMES.Search(arg->type.type.data), arg->name.data, + arg->type.dimension)); + arg = arg->next; + } + + if (0 != strcmp(method->type.type.data, "void")) { + bool isNumeric = is_numeric_java_type(method->type.type.data); + bool isBoolean = 0 == strcmp(method->type.type.data, "boolean"); + + if (isNumeric && method->type.dimension == 0) { + noOpMethod->statements->Add(new ReturnStatement(new LiteralExpression("0"))); + } else if (isBoolean && method->type.dimension == 0) { + noOpMethod->statements->Add(new ReturnStatement(FALSE_VALUE)); + } else { + noOpMethod->statements->Add(new ReturnStatement(NULL_VALUE)); + } + } + noOpMethod->exceptions.push_back(REMOTE_EXCEPTION_TYPE); + noOpClass->elements.push_back(noOpMethod); + } // == the stub method ==================================================== Case* c = new Case(transactCodeName); @@ -520,7 +597,7 @@ generate_interface_descriptors(StubClass* stub, ProxyClass* proxy) } Class* -generate_binder_interface_class(const interface_type* iface) +generate_binder_interface_class(const interface_type* iface, int flags) { InterfaceType* interfaceType = static_cast<InterfaceType*>( NAMES.Find(iface->package, iface->name.data)); @@ -533,6 +610,15 @@ generate_binder_interface_class(const interface_type* iface) interface->type = interfaceType; interface->interfaces.push_back(IINTERFACE_TYPE); + // the No-Op inner class + DefaultNoOpClass* noOpClass = NULL; + if ((flags & GENERATE_NO_OP_CLASS) != 0) { + noOpClass = new DefaultNoOpClass( + NAMES.Find(iface->package, append(iface->name.data, ".NoOp").c_str()), + interfaceType); + interface->elements.push_back(noOpClass); + } + // the stub inner class StubClass* stub = new StubClass( NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()), @@ -555,7 +641,8 @@ generate_binder_interface_class(const interface_type* iface) while (item != NULL) { if (item->item_type == METHOD_TYPE) { method_type * method_item = (method_type*) item; - generate_method(method_item, interface, stub, proxy, method_item->assigned_id); + generate_method(method_item, interface, stub, proxy, noOpClass, + method_item->assigned_id); } item = item->next; index++; diff --git a/tools/aidl/options.cpp b/tools/aidl/options.cpp index 7b2daeb..9de1957 100644 --- a/tools/aidl/options.cpp +++ b/tools/aidl/options.cpp @@ -51,6 +51,7 @@ parse_options(int argc, const char* const* argv, Options *options) options->task = COMPILE_AIDL; options->failOnParcelable = false; options->autoDepFile = false; + options->generateNoOpMethods = false; // OPTIONS while (i < argc) { @@ -97,6 +98,9 @@ parse_options(int argc, const char* const* argv, Options *options) else if (len == 2 && s[1] == 'b') { options->failOnParcelable = true; } + else if (s[1] == 'n') { + options->generateNoOpMethods = true; + } else { // s[1] is not known fprintf(stderr, "unknown option (%d): %s\n", i, s); diff --git a/tools/aidl/options.h b/tools/aidl/options.h index 387e37d..969cc1c 100644 --- a/tools/aidl/options.h +++ b/tools/aidl/options.h @@ -24,6 +24,7 @@ struct Options string outputBaseFolder; string depFileName; bool autoDepFile; + bool generateNoOpMethods; vector<string> filesToPreprocess; }; |