Add read/write for List<ParcelFileDescriptor> in Java
While ParcelableFileDescriptor is built-in type, it IS a parcelable. So
we can treat it just like defined parcelable types when reading/writing.
Bug: 171229850
Test: aidl_unittests / aidl_integration_test
Change-Id: I2fac70a80a39ce0ccae5c91b09e4d331333ec758
diff --git a/aidl_to_java.cpp b/aidl_to_java.cpp
index c5d3f97..9fa691a 100644
--- a/aidl_to_java.cpp
+++ b/aidl_to_java.cpp
@@ -264,18 +264,14 @@
[](const CodeGeneratorContext& c) {
if (c.type.IsGeneric()) {
const string& contained_type = c.type.GetTypeParameters().at(0)->GetName();
- if (AidlTypenames::IsBuiltinTypename(contained_type)) {
- if (contained_type == "String") {
- c.writer << c.parcel << ".writeStringList(" << c.var << ");\n";
- } else if (contained_type == "IBinder") {
- c.writer << c.parcel << ".writeBinderList(" << c.var << ");\n";
- }
+ if (contained_type == "String") {
+ c.writer << c.parcel << ".writeStringList(" << c.var << ");\n";
+ } else if (contained_type == "IBinder") {
+ c.writer << c.parcel << ".writeBinderList(" << c.var << ");\n";
+ } else if (c.typenames.IsParcelable(contained_type)) {
+ c.writer << c.parcel << ".writeTypedList(" << c.var << ");\n";
} else {
- const AidlDefinedType* t = c.typenames.TryGetDefinedType(contained_type);
- AIDL_FATAL_IF(t == nullptr, c.type) << "Unknown type: " << contained_type;
- if (t->AsParcelable() != nullptr) {
- c.writer << c.parcel << ".writeTypedList(" << c.var << ");\n";
- }
+ AIDL_FATAL(c.type) << "write: NOT IMPLEMENTED for " << contained_type;
}
} else {
c.writer << c.parcel << ".writeList(" << c.var << ");\n";
@@ -492,20 +488,16 @@
[](const CodeGeneratorContext& c) {
if (c.type.IsGeneric()) {
const string& contained_type = c.type.GetTypeParameters().at(0)->GetName();
- if (AidlTypenames::IsBuiltinTypename(contained_type)) {
- if (contained_type == "String") {
- c.writer << c.var << " = " << c.parcel << ".createStringArrayList();\n";
- } else if (contained_type == "IBinder") {
- c.writer << c.var << " = " << c.parcel << ".createBinderArrayList();\n";
- }
+ if (contained_type == "String") {
+ c.writer << c.var << " = " << c.parcel << ".createStringArrayList();\n";
+ } else if (contained_type == "IBinder") {
+ c.writer << c.var << " = " << c.parcel << ".createBinderArrayList();\n";
+ } else if (c.typenames.IsParcelable(contained_type)) {
+ c.writer << c.var << " = " << c.parcel << ".createTypedArrayList("
+ << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
+ << ".CREATOR);\n";
} else {
- const AidlDefinedType* t = c.typenames.TryGetDefinedType(contained_type);
- AIDL_FATAL_IF(t == nullptr, c.type) << "Unknown type: " << contained_type;
- if (t->AsParcelable() != nullptr) {
- c.writer << c.var << " = " << c.parcel << ".createTypedArrayList("
- << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
- << ".CREATOR);\n";
- }
+ AIDL_FATAL(c.type) << "create: NOT IMPLEMENTED for " << contained_type;
}
} else {
const string classloader = EnsureAndGetClassloader(const_cast<CodeGeneratorContext&>(c));
@@ -682,20 +674,16 @@
[](const CodeGeneratorContext& c) {
if (c.type.IsGeneric()) {
const string& contained_type = c.type.GetTypeParameters().at(0)->GetName();
- if (AidlTypenames::IsBuiltinTypename(contained_type)) {
- if (contained_type == "String") {
- c.writer << c.parcel << ".readStringList(" << c.var << ");\n";
- } else if (contained_type == "IBinder") {
- c.writer << c.parcel << ".readBinderList(" << c.var << ");\n";
- }
+ if (contained_type == "String") {
+ c.writer << c.parcel << ".readStringList(" << c.var << ");\n";
+ } else if (contained_type == "IBinder") {
+ c.writer << c.parcel << ".readBinderList(" << c.var << ");\n";
+ } else if (c.typenames.IsParcelable(contained_type)) {
+ c.writer << c.parcel << ".readTypedList(" << c.var << ", "
+ << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
+ << ".CREATOR);\n";
} else {
- const AidlDefinedType* t = c.typenames.TryGetDefinedType(contained_type);
- AIDL_FATAL_IF(t == nullptr, c.type) << "Unknown type: " << contained_type;
- if (t->AsParcelable() != nullptr) {
- c.writer << c.parcel << ".readTypedList(" << c.var << ", "
- << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
- << ".CREATOR);\n";
- }
+ AIDL_FATAL(c.type) << "read: NOT IMPLEMENTED for " << contained_type;
}
} else {
const string classloader = EnsureAndGetClassloader(const_cast<CodeGeneratorContext&>(c));
diff --git a/aidl_typenames.cpp b/aidl_typenames.cpp
index 16afbf6..acad42f 100644
--- a/aidl_typenames.cpp
+++ b/aidl_typenames.cpp
@@ -157,6 +157,16 @@
return kPrimitiveTypes.find(type_name) != kPrimitiveTypes.end();
}
+bool AidlTypenames::IsParcelable(const string& type_name) const {
+ if (IsBuiltinTypename(type_name)) {
+ return type_name == "ParcelableHolder" || type_name == "ParcelFileDescriptor";
+ }
+ if (auto defined_type = TryGetDefinedType(type_name); defined_type) {
+ return defined_type->AsParcelable() != nullptr;
+ }
+ return false;
+}
+
const AidlDefinedType* AidlTypenames::TryGetDefinedType(const string& type_name) const {
return TryGetDefinedTypeImpl(type_name).type;
}
diff --git a/aidl_typenames.h b/aidl_typenames.h
index 7ae3690..ca41009 100644
--- a/aidl_typenames.h
+++ b/aidl_typenames.h
@@ -60,6 +60,7 @@
bool AddPreprocessedType(unique_ptr<AidlDefinedType> type);
static bool IsBuiltinTypename(const string& type_name);
static bool IsPrimitiveTypename(const string& type_name);
+ bool IsParcelable(const string& type_name) const;
const AidlDefinedType* TryGetDefinedType(const string& type_name) const;
std::vector<AidlDefinedType*> AllDefinedTypes() const;
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 16356ae..60f99ef 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -120,6 +120,7 @@
else {
_aidl_parcel.writeInt(0);
}
+ _aidl_parcel.writeTypedList(fds);
int _aidl_end_pos = _aidl_parcel.dataPosition();
_aidl_parcel.setDataPosition(_aidl_start_pos);
_aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);
@@ -142,6 +143,7 @@
fd = null;
}
if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
+ fds = _aidl_parcel.createTypedArrayList(android.os.ParcelFileDescriptor.CREATOR);
if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
} finally {
if (_aidl_start_pos > (Integer.MAX_VALUE - _aidl_parcelable_size)) {