summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aidl.cpp7
-rw-r--r--generate_java.cpp4
-rw-r--r--generate_java.h8
-rw-r--r--generate_java_binder.cpp90
-rw-r--r--options.cpp3
-rw-r--r--options.h1
-rw-r--r--type_java.cpp14
-rw-r--r--type_java.h4
8 files changed, 120 insertions, 11 deletions
diff --git a/aidl.cpp b/aidl.cpp
index 142f5f2..9f93d30 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -741,8 +741,13 @@ int compile_aidl_to_java(const JavaOptions& options,
return 1;
}
+ unsigned int flags = 0;
+ if (options.generate_no_op_methods_) {
+ flags |= GENERATE_NO_OP_CLASS;
+ }
+
return generate_java(output_file_name, options.input_file_name_.c_str(),
- interface.get(), types.get(), io_delegate);
+ interface.get(), types.get(), io_delegate, flags);
}
bool preprocess_aidl(const JavaOptions& options,
diff --git a/generate_java.cpp b/generate_java.cpp
index 14df353..3d485d9 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -56,8 +56,8 @@ namespace java {
int generate_java(const string& filename, const string& originalSrc,
AidlInterface* iface, JavaTypeNamespace* types,
- const IoDelegate& io_delegate) {
- Class* cl = generate_binder_interface_class(iface, types);
+ const IoDelegate& io_delegate, unsigned int flags) {
+ Class* cl = generate_binder_interface_class(iface, types, flags);
Document* document = new Document(
"" /* no comment */,
diff --git a/generate_java.h b/generate_java.h
index ed04ba1..eafef88 100644
--- a/generate_java.h
+++ b/generate_java.h
@@ -32,10 +32,11 @@ class JavaTypeNamespace;
int generate_java(const std::string& filename, const std::string& originalSrc,
AidlInterface* iface, java::JavaTypeNamespace* types,
- const IoDelegate& io_delegate);
+ const IoDelegate& io_delegate, unsigned int flags);
android::aidl::java::Class* generate_binder_interface_class(
- const AidlInterface* iface, java::JavaTypeNamespace* types);
+ const AidlInterface* iface, java::JavaTypeNamespace* types,
+ unsigned int flags);
} // namespace java
@@ -59,4 +60,7 @@ class VariableFactory {
} // namespace android
} // namespace aidl
+// Flags that can be passed to generate_java
+#define GENERATE_NO_OP_CLASS 1 << 0
+
#endif // AIDL_GENERATE_JAVA_H_
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 2d2ba68..88d9690 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -220,6 +220,36 @@ ProxyClass::ProxyClass(const JavaTypeNamespace* types, const Type* type,
ProxyClass::~ProxyClass() {}
// =================================================
+class DefaultNoOpClass : public Class {
+ public:
+ DefaultNoOpClass(const JavaTypeNamespace* types, const Type* type,
+ const InterfaceType* interfaceType);
+ virtual ~DefaultNoOpClass();
+};
+
+DefaultNoOpClass::DefaultNoOpClass(const JavaTypeNamespace* types, const Type* type,
+ const 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 = types->IBinderType();
+ 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(const Type* t, StatementBlock* addTo,
Variable* v, Variable* parcel,
JavaTypeNamespace* types) {
@@ -258,8 +288,22 @@ static void generate_string_constant(const AidlStringConstant& constant,
interface->elements.push_back(decl);
}
+static bool is_numeric_java_type(const std::string name) {
+ static const char* KEYWORDS[] = { "int", "byte", "char", "float", "double",
+ "short", "long", NULL };
+ const char** k = KEYWORDS;
+ while (*k) {
+ if (name == *k) {
+ return true;
+ }
+ k++;
+ }
+ return false;
+}
+
static void generate_method(const AidlMethod& method, Class* interface,
StubClass* stubClass, ProxyClass* proxyClass,
+ DefaultNoOpClass *noOpClass,
int index, JavaTypeNamespace* types) {
int i;
@@ -296,6 +340,39 @@ static void generate_method(const AidlMethod& method, Class* interface,
interface->elements.push_back(decl);
+ // == the no-op method ===================================================
+
+ if (noOpClass != NULL) {
+ Method* noOpMethod = new Method;
+ noOpMethod->comment = method.GetComments();
+ noOpMethod->modifiers = OVERRIDE | PUBLIC;
+ noOpMethod->returnType = method.GetType().GetLanguageType<Type>();
+ noOpMethod->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
+ noOpMethod->name = method.GetName();
+ noOpMethod->statements = new StatementBlock;
+ for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+ noOpMethod->parameters.push_back(
+ new Variable(arg->GetType().GetLanguageType<Type>(), arg->GetName(),
+ arg->GetType().IsArray() ? 1 : 0));
+ }
+
+ std::string typeName = method.GetType().GetLanguageType<Type>()->JavaType();
+ if (typeName != "void") {
+ bool isNumeric = is_numeric_java_type(typeName);
+ bool isBoolean = typeName == "boolean";
+
+ if (isNumeric && !method.GetType().IsArray()) {
+ noOpMethod->statements->Add(new ReturnStatement(new LiteralExpression("0")));
+ } else if (isBoolean && !method.GetType().IsArray()) {
+ noOpMethod->statements->Add(new ReturnStatement(FALSE_VALUE));
+ } else {
+ noOpMethod->statements->Add(new ReturnStatement(NULL_VALUE));
+ }
+ }
+ noOpMethod->exceptions.push_back(types->RemoteExceptionType());
+ noOpClass->elements.push_back(noOpMethod);
+ }
+
// == the stub method ====================================================
Case* c = new Case(transactCodeName);
@@ -509,7 +586,8 @@ static void generate_interface_descriptors(StubClass* stub, ProxyClass* proxy,
}
Class* generate_binder_interface_class(const AidlInterface* iface,
- JavaTypeNamespace* types) {
+ JavaTypeNamespace* types,
+ unsigned int flags) {
const InterfaceType* interfaceType = iface->GetLanguageType<InterfaceType>();
// the interface class
@@ -520,6 +598,14 @@ Class* generate_binder_interface_class(const AidlInterface* iface,
interface->type = interfaceType;
interface->interfaces.push_back(types->IInterfaceType());
+ // the No-Op inner class
+ DefaultNoOpClass* noOpClass = NULL;
+ if ((flags & GENERATE_NO_OP_CLASS) != 0) {
+ noOpClass =
+ new DefaultNoOpClass(types, interfaceType->GetNoOp(), interfaceType);
+ interface->elements.push_back(noOpClass);
+ }
+
// the stub inner class
StubClass* stub =
new StubClass(interfaceType->GetStub(), interfaceType, types);
@@ -543,7 +629,7 @@ Class* generate_binder_interface_class(const AidlInterface* iface,
// all the declared methods of the interface
for (const auto& item : iface->GetMethods()) {
- generate_method(*item, interface, stub, proxy, item->GetId(), types);
+ generate_method(*item, interface, stub, proxy, noOpClass, item->GetId(), types);
}
return interface;
diff --git a/options.cpp b/options.cpp
index 72c7575..5639ffd 100644
--- a/options.cpp
+++ b/options.cpp
@@ -48,6 +48,7 @@ unique_ptr<JavaOptions> java_usage() {
" -p<FILE> file created by --preprocess to import.\n"
" -o<FOLDER> base output folder for generated files.\n"
" -b fail when trying to compile a parcelable.\n"
+ " -n generate no-op classes.\n"
"\n"
"INPUT:\n"
" An aidl interface file.\n"
@@ -126,6 +127,8 @@ unique_ptr<JavaOptions> JavaOptions::Parse(int argc, const char* const* argv) {
options->fail_on_parcelable_ = true;
} else if (strcmp(s, "-ninja") == 0) {
options->dep_file_ninja_ = true;
+ } else if (s[1] == 'n') {
+ options->generate_no_op_methods_ = true;
} else {
// s[1] is not known
fprintf(stderr, "unknown option (%d): %s\n", i, s);
diff --git a/options.h b/options.h
index 89a4412..e292389 100644
--- a/options.h
+++ b/options.h
@@ -55,6 +55,7 @@ class JavaOptions final {
bool auto_dep_file_{false};
bool dep_file_ninja_{false};
std::vector<std::string> files_to_preprocess_;
+ bool generate_no_op_methods_{false};
private:
JavaOptions() = default;
diff --git a/type_java.cpp b/type_java.cpp
index 18d27a2..0e9be88 100644
--- a/type_java.cpp
+++ b/type_java.cpp
@@ -682,13 +682,15 @@ void UserDataArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
InterfaceType::InterfaceType(const JavaTypeNamespace* types,
const string& package, const string& name,
bool builtIn, bool oneway, const string& declFile,
- int declLine, const Type* stub, const Type* proxy)
+ int declLine, const Type* stub, const Type* proxy,
+ const Type* no_op)
: Type(types, package, name, builtIn ? ValidatableType::KIND_BUILT_IN
: ValidatableType::KIND_INTERFACE,
true, false, declFile, declLine),
m_oneway(oneway),
stub_(stub),
- proxy_(proxy) {}
+ proxy_(proxy),
+ no_op_(no_op) {}
bool InterfaceType::OneWay() const { return m_oneway; }
@@ -877,14 +879,20 @@ bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
b.GetName() + ".Stub.Proxy",
ValidatableType::KIND_GENERATED,
false, false, filename, b.GetLine());
+ Type* no_op = new Type(this, b.GetPackage(),
+ b.GetName() + ".NoOp",
+ ValidatableType::KIND_GENERATED,
+ false, false, filename, b.GetLine());
+
Type* type =
new InterfaceType(this, b.GetPackage(), b.GetName(), false,
- b.IsOneway(), filename, b.GetLine(), stub, proxy);
+ b.IsOneway(), filename, b.GetLine(), stub, proxy, no_op);
bool success = true;
success &= Add(type);
success &= Add(stub);
success &= Add(proxy);
+ success &= Add(no_op);
return success;
}
diff --git a/type_java.h b/type_java.h
index 6d35f2a..22d4bfe 100644
--- a/type_java.h
+++ b/type_java.h
@@ -389,7 +389,7 @@ class InterfaceType : public Type {
InterfaceType(const JavaTypeNamespace* types, const std::string& package,
const std::string& name, bool builtIn, bool oneway,
const std::string& declFile, int declLine, const Type* stub,
- const Type* proxy);
+ const Type* proxy, const Type* no_op);
bool OneWay() const;
@@ -400,11 +400,13 @@ class InterfaceType : public Type {
const ValidatableType* NullableType() const override { return this; }
const Type* GetStub() const { return stub_; }
const Type* GetProxy() const { return proxy_; }
+ const Type* GetNoOp() const { return no_op_; }
private:
bool m_oneway;
const Type* stub_;
const Type* proxy_;
+ const Type* no_op_;
};
class ClassLoaderType : public Type {