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

Commit 7db766c3 authored by Joe Onorato's avatar Joe Onorato Committed by Mike Lockwood
Browse files

Support custom flattenable types for RPC.

parent 93fcaca2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -114,7 +114,7 @@ struct Statement
    virtual void Write(FILE* to) = 0;
};

struct StatementBlock
struct StatementBlock : public Statement
{
    vector<Statement*> statements;

+100 −31
Original line number Diff line number Diff line
@@ -82,8 +82,7 @@ register_base_types()
    STRING_TYPE = new StringType();
    NAMES.Add(STRING_TYPE);

    OBJECT_TYPE = new Type("java.lang", "Object",
            Type::BUILT_IN, false, false);
    OBJECT_TYPE = new Type("java.lang", "Object", Type::BUILT_IN, false, false, false);
    NAMES.Add(OBJECT_TYPE);

    CHAR_SEQUENCE_TYPE = new CharSequenceType();
@@ -95,7 +94,7 @@ register_base_types()
    LIST_TYPE = new ListType();
    NAMES.Add(LIST_TYPE);

    TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false);
    TEXT_UTILS_TYPE = new Type("android.text", "TextUtils", Type::BUILT_IN, false, false, false);
    NAMES.Add(TEXT_UTILS_TYPE);

    REMOTE_EXCEPTION_TYPE = new RemoteExceptionType();
@@ -122,19 +121,18 @@ register_base_types()
    PARCELABLE_INTERFACE_TYPE = new ParcelableInterfaceType();
    NAMES.Add(PARCELABLE_INTERFACE_TYPE);

    CONTEXT_TYPE = new Type("android.content", "Context",
                                    Type::BUILT_IN, false, false);
    CONTEXT_TYPE = new Type("android.content", "Context", Type::BUILT_IN, false, false, false);
    NAMES.Add(CONTEXT_TYPE);

    RPC_SERVICE_BASE_TYPE = new Type("com.android.athome.service", "AndroidAtHomeService",
                                    Type::BUILT_IN, false, false);
                                    Type::BUILT_IN, false, false, false);
    NAMES.Add(RPC_SERVICE_BASE_TYPE);

    RPC_DATA_TYPE = new RpcDataType();
    NAMES.Add(RPC_DATA_TYPE);

    RPC_BROKER_TYPE = new Type("com.android.athome.utils", "AndroidAtHomeBroker",
                                    Type::BUILT_IN, false, false);
                                    Type::BUILT_IN, false, false, false);
    NAMES.Add(RPC_BROKER_TYPE);

    RPC_ENDPOINT_INFO_TYPE = new ParcelableType("com.android.athome.rpc", "EndpointInfo",
@@ -150,7 +148,7 @@ register_base_types()
    NAMES.Add(RPC_ERROR_TYPE);

    RPC_ERROR_LISTENER_TYPE = new Type("com.android.athome.rpc", "RpcErrorHandler",
                                    Type::BUILT_IN, false, false);
                                    Type::BUILT_IN, false, false, false);
    NAMES.Add(RPC_ERROR_LISTENER_TYPE);

    CLASSLOADER_TYPE = new ClassLoaderType();
@@ -179,27 +177,30 @@ make_generic_type(const string& package, const string& name,

// ================================================================

Type::Type(const string& name, int kind, bool canWriteToParcel, bool canBeOut)
Type::Type(const string& name, int kind, bool canWriteToParcel, bool canWriteToRpcData,
        bool canBeOut)
    :m_package(),
     m_name(name),
     m_declFile(""),
     m_declLine(-1),
     m_kind(kind),
     m_canWriteToParcel(canWriteToParcel),
     m_canWriteToRpcData(canWriteToRpcData),
     m_canBeOut(canBeOut)
{
    m_qualifiedName = name;
}

Type::Type(const string& package, const string& name,
            int kind, bool canWriteToParcel, bool canBeOut,
            const string& declFile, int declLine)
            int kind, bool canWriteToParcel, bool canWriteToRpcData,
            bool canBeOut, const string& declFile, int declLine)
    :m_package(package),
     m_name(name),
     m_declFile(declFile),
     m_declLine(declLine),
     m_kind(kind),
     m_canWriteToParcel(canWriteToParcel),
     m_canWriteToRpcData(canWriteToRpcData),
     m_canBeOut(canBeOut)
{
    if (package.length() > 0) {
@@ -339,7 +340,7 @@ BasicType::BasicType(const string& name, const string& marshallParcel,
          const string& createArrayParcel, const string& readArrayParcel,
          const string& marshallRpc, const string& unmarshallRpc,
          const string& writeArrayRpc, const string& createArrayRpc, const string& readArrayRpc)
    :Type(name, BUILT_IN, true, false),
    :Type(name, BUILT_IN, true, true, false),
     m_marshallParcel(marshallParcel),
     m_unmarshallParcel(unmarshallParcel),
     m_writeArrayParcel(writeArrayParcel),
@@ -407,7 +408,7 @@ BasicType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
// ================================================================

BooleanType::BooleanType()
    :Type("boolean", BUILT_IN, true, false)
    :Type("boolean", BUILT_IN, true, true, false)
{
}

@@ -468,7 +469,7 @@ BooleanType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v
// ================================================================

CharType::CharType()
    :Type("char", BUILT_IN, true, false)
    :Type("char", BUILT_IN, true, true, false)
{
}

@@ -527,7 +528,7 @@ CharType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, V
// ================================================================

StringType::StringType()
    :Type("java.lang", "String", BUILT_IN, true, false)
    :Type("java.lang", "String", BUILT_IN, true, true, false)
{
}

@@ -591,7 +592,7 @@ StringType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
// ================================================================

CharSequenceType::CharSequenceType()
    :Type("java.lang", "CharSequence", BUILT_IN, true, false)
    :Type("java.lang", "CharSequence", BUILT_IN, true, true, false)
{
}

@@ -651,7 +652,7 @@ CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
// ================================================================

RemoteExceptionType::RemoteExceptionType()
    :Type("android.os", "RemoteException", BUILT_IN, false, false)
    :Type("android.os", "RemoteException", BUILT_IN, false, false, false)
{
}

@@ -670,7 +671,7 @@ RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variab
// ================================================================

RuntimeExceptionType::RuntimeExceptionType()
    :Type("java.lang", "RuntimeException", BUILT_IN, false, false)
    :Type("java.lang", "RuntimeException", BUILT_IN, false, false, false)
{
}

@@ -690,7 +691,7 @@ RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v, Varia
// ================================================================

IBinderType::IBinderType()
    :Type("android.os", "IBinder", BUILT_IN, true, false)
    :Type("android.os", "IBinder", BUILT_IN, true, false, false)
{
}

@@ -729,7 +730,7 @@ IBinderType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* p
// ================================================================

IInterfaceType::IInterfaceType()
    :Type("android.os", "IInterface", BUILT_IN, false, false)
    :Type("android.os", "IInterface", BUILT_IN, false, false, false)
{
}

@@ -749,7 +750,7 @@ IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* p
// ================================================================

BinderType::BinderType()
    :Type("android.os", "Binder", BUILT_IN, false, false)
    :Type("android.os", "Binder", BUILT_IN, false, false, false)
{
}

@@ -770,7 +771,7 @@ BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
// ================================================================

BinderProxyType::BinderProxyType()
    :Type("android.os", "BinderProxy", BUILT_IN, false, false)
    :Type("android.os", "BinderProxy", BUILT_IN, false, false, false)
{
}

@@ -791,7 +792,7 @@ BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
// ================================================================

ParcelType::ParcelType()
    :Type("android.os", "Parcel", BUILT_IN, false, false)
    :Type("android.os", "Parcel", BUILT_IN, false, false, false)
{
}

@@ -810,7 +811,7 @@ ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parce
// ================================================================

ParcelableInterfaceType::ParcelableInterfaceType()
    :Type("android.os", "Parcelable", BUILT_IN, false, false)
    :Type("android.os", "Parcelable", BUILT_IN, false, false, false)
{
}

@@ -829,7 +830,7 @@ ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Va
// ================================================================

MapType::MapType()
    :Type("java.util", "Map", BUILT_IN, true, true)
    :Type("java.util", "Map", BUILT_IN, true, false, true)
{
}

@@ -869,7 +870,7 @@ MapType::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Va
// ================================================================

ListType::ListType()
    :Type("java.util", "List", BUILT_IN, true, true)
    :Type("java.util", "List", BUILT_IN, true, true, true)
{
}

@@ -918,7 +919,7 @@ ListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, V

ParcelableType::ParcelableType(const string& package, const string& name,
                        bool builtIn, const string& declFile, int declLine)
    :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, true,
    :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, false, true,
            declFile, declLine)
{
}
@@ -1019,13 +1020,81 @@ ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable
                    v, new LiteralExpression(creator)));
}

// ================================================================

FlattenableType::FlattenableType(const string& package, const string& name,
                        bool builtIn, const string& declFile, int declLine)
    :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, false, true, true,
            declFile, declLine)
{
}

string
FlattenableType::CreatorName() const
{
    return QualifiedName() + ".CREATOR";
}

void
FlattenableType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, int flags)
{
    // if (v != null) {
    //     RpcData _obj = new RpcData();
    //     v.writeToRpcData(_obj);
    //     data.putRpcData(k, obj);
    // }
    IfStatement* ifpart = new IfStatement;
    ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
    Variable* _obj = new Variable(RPC_DATA_TYPE, "_obj");
    ifpart->statements->Add(new VariableDeclaration(_obj, new NewExpression(RPC_DATA_TYPE)));
    ifpart->statements->Add(new MethodCall(v, "writeToRpcData", 1, _obj));
    ifpart->statements->Add(new MethodCall(data, "putRpcData", 2, k, _obj));

    addTo->Add(ifpart);
}

void
FlattenableType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, Variable** cl)
{
    // RpcData _obj_XX = data.getRpcData(k);
    // if (_data_XX != null)
    //     v = CLASS.RPC_CREATOR.createFromParcel(parcel)
    // } else {
    //     v = null;
    // }

    StatementBlock* block = new StatementBlock;
    addTo->Add(block);

    Variable* _obj = new Variable(RPC_DATA_TYPE, "_obj");
    block->Add(new VariableDeclaration(_obj, new MethodCall(data, "getRpcData", 1, k)));

    IfStatement* ifpart = new IfStatement();
    ifpart->expression = new Comparison(_obj, "!=", NULL_VALUE);
    ifpart->statements->Add(new Assignment(v,
                new MethodCall(v->type, "RPC_CREATOR.createFromRpcData", 1, data)));

    IfStatement* elsepart = new IfStatement();
    ifpart->elseif = elsepart;
    elsepart->statements->Add(new Assignment(v, NULL_VALUE));

    block->Add(ifpart);
}

bool
FlattenableType::CanBeArray() const
{
    return true;
}

// ================================================================

InterfaceType::InterfaceType(const string& package, const string& name,
                        bool builtIn, bool oneway,
                        const string& declFile, int declLine)
    :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false,
    :Type(package, name, builtIn ? BUILT_IN : INTERFACE, true, false, false,
                        declFile, declLine)
    ,m_oneway(oneway)
{
@@ -1064,7 +1133,7 @@ InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* pa

GenericType::GenericType(const string& package, const string& name,
                         const vector<Type*>& args)
    :Type(package, name, BUILT_IN, true, true)
    :Type(package, name, BUILT_IN, true, true, true)
{
    m_args = args;

@@ -1210,7 +1279,7 @@ GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variabl
// ================================================================

RpcDataType::RpcDataType()
    :Type("com.android.athome.rpc", "RpcData", Type::BUILT_IN, false, false)
    :Type("com.android.athome.rpc", "RpcData", Type::BUILT_IN, false, true, true)
{
}

@@ -1232,7 +1301,7 @@ RpcDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v
// ================================================================

ClassLoaderType::ClassLoaderType()
    :Type("java.lang", "ClassLoader", BUILT_IN, false, false)
    :Type("java.lang", "ClassLoader", BUILT_IN, false, false, false)
{
}

+21 −3
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ public:
    };

                    Type(const string& name, int kind, bool canWriteToParcel,
                            bool canBeOut);
                            bool canWriteToRpcData, bool canBeOut);
                    Type(const string& package, const string& name,
                            int kind, bool canWriteToParcel, bool canBeOut,
                            int kind, bool canWriteToParcel, bool canWriteToRpcData, bool canBeOut,
                            const string& declFile = "", int declLine = -1);
    virtual         ~Type();

@@ -36,7 +36,8 @@ public:
    inline int      Kind() const                { return m_kind; }
    inline string   DeclFile() const            { return m_declFile; }
    inline int      DeclLine() const            { return m_declLine; }
    inline bool     CanBeMarshalled() const     { return m_canWriteToParcel; }
    inline bool     CanWriteToParcel() const    { return m_canWriteToParcel; }
    inline bool     CanWriteToRpcData() const   { return m_canWriteToRpcData; }
    inline bool     CanBeOutParameter() const   { return m_canBeOut; }
    
    virtual string  ImportType() const;
@@ -79,6 +80,7 @@ private:
    int m_declLine;
    int m_kind;
    bool m_canWriteToParcel;
    bool m_canWriteToRpcData;
    bool m_canBeOut;
};

@@ -373,6 +375,22 @@ public:
                                    Variable* parcel, Variable** cl);
};

class FlattenableType : public Type
{
public:
                    FlattenableType(const string& package, const string& name,
                            bool builtIn, const string& declFile, int declLine);

    virtual string  CreatorName() const;

    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, int flags);
    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, Variable** cl);

    virtual bool    CanBeArray() const;
};

class InterfaceType : public Type
{
public:
+53 −15
Original line number Diff line number Diff line
@@ -54,6 +54,10 @@ test_document(document_item_type* d)
            parcelable_type* b = (parcelable_type*)d;
            printf("parcelable %s %s;\n", b->package, b->name.data);
        }
        else if (d->item_type == FLATTENABLE_TYPE) {
            parcelable_type* b = (parcelable_type*)d;
            printf("flattenable %s %s;\n", b->package, b->name.data);
        }
        else {
            printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
        }
@@ -238,7 +242,8 @@ check_filenames(const char* filename, document_item_type* items)
{
    int err = 0;
    while (items) {
        if (items->item_type == PARCELABLE_TYPE) {
        if (items->item_type == PARCELABLE_TYPE
                || items->item_type == FLATTENABLE_TYPE) {
            parcelable_type* p = (parcelable_type*)items;
            err |= check_filename(filename, p->package, &p->name);
        }
@@ -296,6 +301,11 @@ gather_types(const char* filename, document_item_type* items)
            type = new ParcelableType(p->package ? p->package : "",
                            p->name.data, false, filename, p->name.lineno);
        }
        else if (items->item_type == FLATTENABLE_TYPE) {
            parcelable_type* p = (parcelable_type*)items;
            type = new FlattenableType(p->package ? p->package : "",
                            p->name.data, false, filename, p->name.lineno);
        }
        else if (items->item_type == INTERFACE_TYPE_BINDER
                || items->item_type == INTERFACE_TYPE_RPC) {
            interface_type* c = (interface_type*)items;
@@ -321,14 +331,14 @@ gather_types(const char* filename, document_item_type* items)
                string name = c->name.data;
                name += ".Stub";
                Type* stub = new Type(c->package ? c->package : "",
                                        name, Type::GENERATED, false, false,
                                        name, Type::GENERATED, false, false, false,
                                        filename, c->name.lineno);
                NAMES.Add(stub);

                name = c->name.data;
                name += ".Stub.Proxy";
                Type* proxy = new Type(c->package ? c->package : "",
                                        name, Type::GENERATED, false, false,
                                        name, Type::GENERATED, false, false, false,
                                        filename, c->name.lineno);
                NAMES.Add(proxy);
            }
@@ -341,7 +351,7 @@ gather_types(const char* filename, document_item_type* items)
                string name = c->name.data;
                name += ".ServiceBase";
                Type* base = new Type(c->package ? c->package : "",
                                        name, Type::GENERATED, false, false,
                                        name, Type::GENERATED, false, false, false,
                                        filename, c->name.lineno);
                NAMES.Add(base);
            }
@@ -396,7 +406,7 @@ matches_keyword(const char* str)
}

static int
check_method(const char* filename, method_type* m)
check_method(const char* filename, int kind, method_type* m)
{
    int err = 0;

@@ -409,7 +419,8 @@ check_method(const char* filename, method_type* m)
        return err;
    }

    if (!returnType->CanBeMarshalled()) {
    if (!(kind == INTERFACE_TYPE_BINDER ? returnType->CanWriteToParcel()
                : returnType->CanWriteToRpcData())) {
        fprintf(stderr, "%s:%d return type %s can't be marshalled.\n", filename,
                    m->type.type.lineno, m->type.type.data);
        err = 1;
@@ -445,7 +456,7 @@ check_method(const char* filename, method_type* m)
            goto next;
        }
        
        if (!t->CanBeMarshalled()) {
        if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
            fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
                        filename, m->type.type.lineno, index,
                        arg->type.type.data, arg->name.data);
@@ -512,8 +523,9 @@ check_types(const char* filename, document_item_type* items)
{
    int err = 0;
    while (items) {
        // (nothing to check for PARCELABLE_TYPE)
        if (items->item_type == INTERFACE_TYPE_BINDER) {
        // (nothing to check for PARCELABLE_TYPE or FLATTENABLE_TYPE)
        if (items->item_type == INTERFACE_TYPE_BINDER
                || items->item_type == INTERFACE_TYPE_RPC) {
            map<string,method_type*> methodNames;
            interface_type* c = (interface_type*)items;

@@ -522,7 +534,7 @@ check_types(const char* filename, document_item_type* items)
                if (member->item_type == METHOD_TYPE) {
                    method_type* m = (method_type*)member;

                    err |= check_method(filename, m);
                    err |= check_method(filename, items->item_type, m);

                    // prevent duplicate methods
                    if (methodNames.find(m->name.data) == methodNames.end()) {
@@ -568,19 +580,22 @@ exactly_one_interface(const char* filename, const document_item_type* items, con
        else if (next->item_type == PARCELABLE_TYPE) {
            lineno = ((parcelable_type*)next)->parcelable_token.lineno;
        }
        else if (next->item_type == FLATTENABLE_TYPE) {
            lineno = ((parcelable_type*)next)->parcelable_token.lineno;
        }
        fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
                            filename, lineno);
        return 1;
    }

    if (items->item_type == PARCELABLE_TYPE) {
    if (items->item_type == PARCELABLE_TYPE || items->item_type == FLATTENABLE_TYPE) {
        *onlyParcelable = true;
        if (options.failOnParcelable) {
            fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
                            " parcelables,\n", filename,
                            " parcelables or flattenables,\n", filename,
                            ((parcelable_type*)items)->parcelable_token.lineno);
            fprintf(stderr, "%s:%d .aidl files that only declare parcelables "
                            "don't need to go in the Makefile.\n", filename,
            fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
                            "may not go in the Makefile.\n", filename,
                            ((parcelable_type*)items)->parcelable_token.lineno);
            return 1;
        }
@@ -680,7 +695,7 @@ generate_outputFileName(const Options& options, const document_item_type* items)
        interface_type* type = (interface_type*)items;

        return generate_outputFileName2(options, type->name, type->package);
    } else if (items->item_type == PARCELABLE_TYPE) {
    } else if (items->item_type == PARCELABLE_TYPE || items->item_type == FLATTENABLE_TYPE) {
        parcelable_type* type = (parcelable_type*)items;
        return generate_outputFileName2(options, type->name, type->package);
    }
@@ -765,6 +780,20 @@ parse_preprocessed_file(const string& filename)
            parcl->semicolon_token.data = strdup(";");
            doc = (document_item_type*)parcl;
        }
        else if (0 == strcmp("flattenable", type)) {
            parcelable_type* parcl = (parcelable_type*)malloc(
                    sizeof(parcelable_type));
            memset(parcl, 0, sizeof(parcelable_type));
            parcl->document_item.item_type = FLATTENABLE_TYPE;
            parcl->parcelable_token.lineno = lineno;
            parcl->parcelable_token.data = strdup(type);
            parcl->package = packagename ? strdup(packagename) : NULL;
            parcl->name.lineno = lineno;
            parcl->name.data = strdup(classname);
            parcl->semicolon_token.lineno = lineno;
            parcl->semicolon_token.data = strdup(";");
            doc = (document_item_type*)parcl;
        }
        else if (0 == strcmp("interface", type)) {
            interface_type* iface = (interface_type*)malloc(
                    sizeof(interface_type));
@@ -949,6 +978,15 @@ preprocess_aidl(const Options& options)
                line += '.';
            }
            line += parcelable->name.data;
        }
        else if (doc->item_type == FLATTENABLE_TYPE) {
            line = "parcelable ";
            parcelable_type* parcelable = (parcelable_type*)doc;
            if (parcelable->package) {
                line += parcelable->package;
                line += '.';
            }
            line += parcelable->name.data;
        } else {
            line = "interface ";
            interface_type* iface = (interface_type*)doc;
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ typedef struct method_type {

enum {
    PARCELABLE_TYPE = 12,
    FLATTENABLE_TYPE,
    INTERFACE_TYPE_BINDER,
    INTERFACE_TYPE_RPC
};
Loading