Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edd2da9b authored by Luis Vidal's avatar Luis Vidal
Browse files

AIDL: Add option to generate No-Op methods

Add the option to generate a default (no-op) implementation
of an interface

Change-Id: I2631e93c8b85e056cf928e9592342dc4466f293e
parent df41276b
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -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;
}
+2 −2
Original line number Diff line number Diff line
@@ -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);
+5 −2
Original line number Diff line number Diff line
@@ -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
+90 −3
Original line number Diff line number Diff line
@@ -193,6 +193,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,
@@ -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++;
+4 −0
Original line number Diff line number Diff line
@@ -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);
Loading