summaryrefslogtreecommitdiffstats
path: root/tools/aidl
diff options
context:
space:
mode:
authorJoe Onorato <joeo@google.com>2011-09-15 21:31:15 -0700
committerJoe Onorato <joeo@google.com>2011-09-19 16:23:18 -0700
commit0ca2a36d8dd783e7ba5abffd5929c0e33c6ba91d (patch)
tree3bc57a64f31f347dbe15e0fef6daddd16a512f29 /tools/aidl
parent4742c0cd30b6e76361cc72182339f0a30efceee2 (diff)
downloadframeworks_base-0ca2a36d8dd783e7ba5abffd5929c0e33c6ba91d.zip
frameworks_base-0ca2a36d8dd783e7ba5abffd5929c0e33c6ba91d.tar.gz
frameworks_base-0ca2a36d8dd783e7ba5abffd5929c0e33c6ba91d.tar.bz2
Support custom flattenable types for RPC.
Diffstat (limited to 'tools/aidl')
-rwxr-xr-xtools/aidl/AST.h2
-rwxr-xr-xtools/aidl/Type.cpp131
-rwxr-xr-xtools/aidl/Type.h24
-rw-r--r--tools/aidl/aidl.cpp68
-rw-r--r--tools/aidl/aidl_language.h1
-rw-r--r--tools/aidl/aidl_language_l.l1
-rw-r--r--tools/aidl/aidl_language_y.y24
-rw-r--r--tools/aidl/generate_java_rpc.cpp6
8 files changed, 203 insertions, 54 deletions
diff --git a/tools/aidl/AST.h b/tools/aidl/AST.h
index bb090e0..ead5e7a 100755
--- a/tools/aidl/AST.h
+++ b/tools/aidl/AST.h
@@ -114,7 +114,7 @@ struct Statement
virtual void Write(FILE* to) = 0;
};
-struct StatementBlock
+struct StatementBlock : public Statement
{
vector<Statement*> statements;
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
index 9a58af0..3590255 100755
--- a/tools/aidl/Type.cpp
+++ b/tools/aidl/Type.cpp
@@ -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)
{
}
diff --git a/tools/aidl/Type.h b/tools/aidl/Type.h
index 97b3a12..fa57840 100755
--- a/tools/aidl/Type.h
+++ b/tools/aidl/Type.h
@@ -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:
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index 78404cb..c39e603 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -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;
diff --git a/tools/aidl/aidl_language.h b/tools/aidl/aidl_language.h
index 985f646..b490a59 100644
--- a/tools/aidl/aidl_language.h
+++ b/tools/aidl/aidl_language.h
@@ -64,6 +64,7 @@ typedef struct method_type {
enum {
PARCELABLE_TYPE = 12,
+ FLATTENABLE_TYPE,
INTERFACE_TYPE_BINDER,
INTERFACE_TYPE_RPC
};
diff --git a/tools/aidl/aidl_language_l.l b/tools/aidl/aidl_language_l.l
index 8092366..7c5290c 100644
--- a/tools/aidl/aidl_language_l.l
+++ b/tools/aidl/aidl_language_l.l
@@ -81,6 +81,7 @@ brackets \[{whitespace}?\]
/* keywords */
parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; }
interface { SET_BUFFER(INTERFACE); return INTERFACE; }
+flattenable { SET_BUFFER(FLATTENABLE); return FLATTENABLE; }
rpc { SET_BUFFER(INTERFACE); return RPC; }
in { SET_BUFFER(IN); return IN; }
out { SET_BUFFER(OUT); return OUT; }
diff --git a/tools/aidl/aidl_language_y.y b/tools/aidl/aidl_language_y.y
index 965d936..12bb3d7 100644
--- a/tools/aidl/aidl_language_y.y
+++ b/tools/aidl/aidl_language_y.y
@@ -19,6 +19,7 @@ static int count_brackets(const char*);
%token ARRAY
%token PARCELABLE
%token INTERFACE
+%token FLATTENABLE
%token RPC
%token IN
%token OUT
@@ -78,7 +79,7 @@ declaration:
;
parcelable_decl:
- PARCELABLE IDENTIFIER ';' {
+ PARCELABLE IDENTIFIER ';' {
parcelable_type* b = (parcelable_type*)malloc(sizeof(parcelable_type));
b->document_item.item_type = PARCELABLE_TYPE;
b->document_item.next = NULL;
@@ -98,6 +99,27 @@ parcelable_decl:
g_currentFilename, $2.buffer.lineno, $2.buffer.data);
$$.parcelable = NULL;
}
+ | FLATTENABLE IDENTIFIER ';' {
+ parcelable_type* b = (parcelable_type*)malloc(sizeof(parcelable_type));
+ b->document_item.item_type = FLATTENABLE_TYPE;
+ b->document_item.next = NULL;
+ b->parcelable_token = $1.buffer;
+ b->name = $2.buffer;
+ b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
+ b->semicolon_token = $3.buffer;
+ $$.parcelable = b;
+ }
+ | FLATTENABLE ';' {
+ fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n",
+ g_currentFilename, $1.buffer.lineno);
+ $$.parcelable = NULL;
+ }
+ | FLATTENABLE error ';' {
+ fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name, saw \"%s\".\n",
+ g_currentFilename, $2.buffer.lineno, $2.buffer.data);
+ $$.parcelable = NULL;
+ }
+
;
interface_header:
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp
index 69e9c3d..53a11f2 100644
--- a/tools/aidl/generate_java_rpc.cpp
+++ b/tools/aidl/generate_java_rpc.cpp
@@ -6,7 +6,7 @@
#include <string.h>
Type* SERVICE_CONTAINER_TYPE = new Type("com.android.athome.service",
- "AndroidAtHomeServiceContainer", Type::BUILT_IN, false, false);
+ "AndroidAtHomeServiceContainer", Type::BUILT_IN, false, false, false);
static string
format_int(int n)
@@ -237,7 +237,7 @@ ResultDispatcherClass::ResultDispatcherClass()
{
this->modifiers = PRIVATE | FINAL;
this->what = Class::CLASS;
- this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false);
+ this->type = new Type("_ResultDispatcher", Type::GENERATED, false, false, false);
this->interfaces.push_back(RPC_RESULT_HANDLER_TYPE);
// methodId
@@ -373,7 +373,7 @@ generate_results_method(const method_type* method, RpcProxyClass* proxyClass)
string resultsMethodName = results_method_name(method->name.data);
Type* resultsInterfaceType = new Type(results_class_name(method->name.data),
- Type::GENERATED, false, false);
+ Type::GENERATED, false, false, false);
if (!method->oneway) {
Class* resultsClass = new Class;