blob: 18d27a24ce387c6128b330c156b9a5848db418df [file] [log] [blame]
/*
* Copyright (C) 2015, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "type_java.h"
#include <sys/types.h>
#include <android-base/strings.h>
#include "aidl_language.h"
#include "logging.h"
using std::string;
using android::base::Split;
using android::base::Join;
using android::base::Trim;
namespace android {
namespace aidl {
namespace java {
Expression* NULL_VALUE;
Expression* THIS_VALUE;
Expression* SUPER_VALUE;
Expression* TRUE_VALUE;
Expression* FALSE_VALUE;
// ================================================================
Type::Type(const JavaTypeNamespace* types, const string& name, int kind,
bool canWriteToParcel, bool canBeOut)
: Type(types, "", name, kind, canWriteToParcel, canBeOut, "", -1) {}
Type::Type(const JavaTypeNamespace* types, const string& package,
const string& name, int kind, bool canWriteToParcel,
bool canBeOut, const string& declFile, int declLine)
: ValidatableType(kind, package, name, declFile, declLine),
m_types(types),
m_javaType((package.empty()) ? name : package + "." + name),
m_canWriteToParcel(canWriteToParcel),
m_canBeOut(canBeOut) {
}
string Type::CreatorName() const { return ""; }
string Type::InstantiableName() const { return JavaType(); }
void Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
int flags) const {
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn", __FILE__,
__LINE__, m_javaType.c_str());
addTo->Add(new LiteralExpression("/* WriteToParcel error " + m_javaType +
" */"));
}
void Type::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
__LINE__, m_javaType.c_str());
addTo->Add(new LiteralExpression("/* CreateFromParcel error " +
m_javaType + " */"));
}
void Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
__LINE__, m_javaType.c_str());
addTo->Add(new LiteralExpression("/* ReadFromParcel error " +
m_javaType + " */"));
}
Expression* Type::BuildWriteToParcelFlags(int flags) const {
if (flags == 0) {
return new LiteralExpression("0");
}
if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
return new FieldVariable(m_types->ParcelableInterfaceType(),
"PARCELABLE_WRITE_RETURN_VALUE");
}
return new LiteralExpression("0");
}
// ================================================================
BasicType::BasicType(const JavaTypeNamespace* types, const string& name,
const string& marshallParcel,
const string& unmarshallParcel,
const string& writeArrayParcel,
const string& createArrayParcel,
const string& readArrayParcel)
: Type(types, name, ValidatableType::KIND_BUILT_IN, true, false),
m_marshallParcel(marshallParcel),
m_unmarshallParcel(unmarshallParcel) {
m_array_type.reset(new BasicArrayType(types, name, writeArrayParcel,
createArrayParcel, readArrayParcel));
}
void BasicType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, m_marshallParcel, 1, v));
}
void BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallParcel)));
}
BasicArrayType::BasicArrayType(const JavaTypeNamespace* types,
const string& name,
const string& writeArrayParcel,
const string& createArrayParcel,
const string& readArrayParcel)
: Type(types, name, ValidatableType::KIND_BUILT_IN, true, true),
m_writeArrayParcel(writeArrayParcel),
m_createArrayParcel(createArrayParcel),
m_readArrayParcel(readArrayParcel) {}
void BasicArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, m_writeArrayParcel, 1, v));
}
void BasicArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayParcel)));
}
void BasicArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
}
// ================================================================
FileDescriptorType::FileDescriptorType(const JavaTypeNamespace* types)
: Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
true, false) {
m_array_type.reset(new FileDescriptorArrayType(types));
}
void FileDescriptorType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeRawFileDescriptor", 1, v));
}
void FileDescriptorType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "readRawFileDescriptor")));
}
FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
: Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
true, true) {}
void FileDescriptorArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeRawFileDescriptorArray", 1, v));
}
void FileDescriptorArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "createRawFileDescriptorArray")));
}
void FileDescriptorArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new MethodCall(parcel, "readRawFileDescriptorArray", 1, v));
}
// ================================================================
BooleanType::BooleanType(const JavaTypeNamespace* types)
: Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, false) {
m_array_type.reset(new BooleanArrayType(types));
}
void BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(
parcel, "writeInt", 1,
new Ternary(v, new LiteralExpression("1"), new LiteralExpression("0"))));
}
void BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(
new Assignment(v, new Comparison(new LiteralExpression("0"), "!=",
new MethodCall(parcel, "readInt"))));
}
BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
: Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, true) {}
void BooleanArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
}
void BooleanArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
}
void BooleanArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
}
// ================================================================
CharType::CharType(const JavaTypeNamespace* types)
: Type(types, "char", ValidatableType::KIND_BUILT_IN, true, false) {
m_array_type.reset(new CharArrayType(types));
}
void CharType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(
new MethodCall(parcel, "writeInt", 1, new Cast(m_types->IntType(), v)));
}
void CharType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
}
CharArrayType::CharArrayType(const JavaTypeNamespace* types)
: Type(types, "char", ValidatableType::KIND_BUILT_IN, true, true) {}
void CharArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
}
void CharArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
}
void CharArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
}
// ================================================================
StringType::StringType(const JavaTypeNamespace* types,
const std::string& package,
const std::string& class_name)
: Type(types, package, class_name,
ValidatableType::KIND_BUILT_IN, true, false) {
m_array_type.reset(new StringArrayType(types));
}
string StringType::CreatorName() const {
return "android.os.Parcel.STRING_CREATOR";
}
void StringType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeString", 1, v));
}
void StringType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
}
StringArrayType::StringArrayType(const JavaTypeNamespace* types)
: Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN,
true, true) {}
string StringArrayType::CreatorName() const {
return "android.os.Parcel.STRING_CREATOR";
}
void StringArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
}
void StringArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
}
void StringArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
}
// ================================================================
CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
: Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN,
true, false) {}
string CharSequenceType::CreatorName() const {
return "android.os.Parcel.STRING_CREATOR";
}
void CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
// if (v != null) {
// parcel.writeInt(1);
// v.writeToParcel(parcel);
// } else {
// parcel.writeInt(0);
// }
IfStatement* elsepart = new IfStatement();
elsepart->statements->Add(
new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
IfStatement* ifpart = new IfStatement;
ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
ifpart->elseif = elsepart;
ifpart->statements->Add(
new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
ifpart->statements->Add(new MethodCall(m_types->TextUtilsType(),
"writeToParcel", 3, v, parcel,
BuildWriteToParcelFlags(flags)));
addTo->Add(ifpart);
}
void CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
// if (0 != parcel.readInt()) {
// v = TextUtils.createFromParcel(parcel)
// } else {
// v = null;
// }
IfStatement* elsepart = new IfStatement();
elsepart->statements->Add(new Assignment(v, NULL_VALUE));
IfStatement* ifpart = new IfStatement();
ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
new MethodCall(parcel, "readInt"));
ifpart->elseif = elsepart;
ifpart->statements->Add(new Assignment(
v, new MethodCall(m_types->TextUtilsType(),
"CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
addTo->Add(ifpart);
}
// ================================================================
RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
: Type(types, "android.os", "RemoteException",
ValidatableType::KIND_BUILT_IN, false, false) {}
void RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
: Type(types, "java.lang", "RuntimeException",
ValidatableType::KIND_BUILT_IN, false, false) {}
void RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel,
Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
IBinderType::IBinderType(const JavaTypeNamespace* types)
: Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
true, false) {
m_array_type.reset(new IBinderArrayType(types));
}
void IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
}
void IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
}
IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
: Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
true, true) {}
void IBinderArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
}
void IBinderArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
}
void IBinderArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
}
// ================================================================
IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
: Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN,
false, false) {}
void IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
BinderType::BinderType(const JavaTypeNamespace* types)
: Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN,
false, false) {}
void BinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
: Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN,
false, false) {}
void BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
ParcelType::ParcelType(const JavaTypeNamespace* types)
: Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN,
false, false) {}
void ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
: Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN,
false, false) {}
void ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
void ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo,
Variable* v, Variable* parcel,
Variable**) const {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
}
// ================================================================
MapType::MapType(const JavaTypeNamespace* types)
: Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN,
true, true) {}
void MapType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
}
static void EnsureClassLoader(StatementBlock* addTo, Variable** cl,
const JavaTypeNamespace* types) {
// We don't want to look up the class loader once for every
// collection argument, so ensure we do it at most once per method.
if (*cl == NULL) {
*cl = new Variable(types->ClassLoaderType(), "cl");
addTo->Add(new VariableDeclaration(
*cl, new LiteralExpression("this.getClass().getClassLoader()"),
types->ClassLoaderType()));
}
}
void MapType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl) const {
EnsureClassLoader(addTo, cl, m_types);
addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
}
void MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl) const {
EnsureClassLoader(addTo, cl, m_types);
addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
}
// ================================================================
ListType::ListType(const JavaTypeNamespace* types)
: Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN,
true, true) {}
string ListType::InstantiableName() const { return "java.util.ArrayList"; }
void ListType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeList", 1, v));
}
void ListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl) const {
EnsureClassLoader(addTo, cl, m_types);
addTo->Add(
new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
}
void ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl) const {
EnsureClassLoader(addTo, cl, m_types);
addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
}
// ================================================================
UserDataType::UserDataType(const JavaTypeNamespace* types,
const string& package, const string& name,
bool builtIn, bool canWriteToParcel,
const string& declFile, int declLine)
: Type(types, package, name,
builtIn ? ValidatableType::KIND_BUILT_IN
: ValidatableType::KIND_PARCELABLE,
canWriteToParcel, true, declFile, declLine) {
m_array_type.reset(new UserDataArrayType(types, package, name, builtIn,
canWriteToParcel, declFile,
declLine));
}
string UserDataType::CreatorName() const {
return JavaType() + ".CREATOR";
}
void UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
// if (v != null) {
// parcel.writeInt(1);
// v.writeToParcel(parcel);
// } else {
// parcel.writeInt(0);
// }
IfStatement* elsepart = new IfStatement();
elsepart->statements->Add(
new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
IfStatement* ifpart = new IfStatement;
ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
ifpart->elseif = elsepart;
ifpart->statements->Add(
new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, parcel,
BuildWriteToParcelFlags(flags)));
addTo->Add(ifpart);
}
void UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
// if (0 != parcel.readInt()) {
// v = CLASS.CREATOR.createFromParcel(parcel)
// } else {
// v = null;
// }
IfStatement* elsepart = new IfStatement();
elsepart->statements->Add(new Assignment(v, NULL_VALUE));
IfStatement* ifpart = new IfStatement();
ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
new MethodCall(parcel, "readInt"));
ifpart->elseif = elsepart;
ifpart->statements->Add(new Assignment(
v, new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
addTo->Add(ifpart);
}
void UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
// TODO: really, we don't need to have this extra check, but we
// don't have two separate marshalling code paths
// if (0 != parcel.readInt()) {
// v.readFromParcel(parcel)
// }
IfStatement* ifpart = new IfStatement();
ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
new MethodCall(parcel, "readInt"));
ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
addTo->Add(ifpart);
}
UserDataArrayType::UserDataArrayType(const JavaTypeNamespace* types,
const string& package, const string& name,
bool builtIn, bool canWriteToParcel,
const string& declFile, int declLine)
: Type(types, package, name,
builtIn ? ValidatableType::KIND_BUILT_IN
: ValidatableType::KIND_PARCELABLE,
canWriteToParcel, true, declFile, declLine) {}
string UserDataArrayType::CreatorName() const {
return JavaType() + ".CREATOR";
}
void UserDataArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
BuildWriteToParcelFlags(flags)));
}
void UserDataArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
string creator = v->type->JavaType() + ".CREATOR";
addTo->Add(new Assignment(v, new MethodCall(parcel, "createTypedArray", 1,
new LiteralExpression(creator))));
}
void UserDataArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
string creator = v->type->JavaType() + ".CREATOR";
addTo->Add(new MethodCall(parcel, "readTypedArray", 2, v,
new LiteralExpression(creator)));
}
// ================================================================
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)
: Type(types, package, name, builtIn ? ValidatableType::KIND_BUILT_IN
: ValidatableType::KIND_INTERFACE,
true, false, declFile, declLine),
m_oneway(oneway),
stub_(stub),
proxy_(proxy) {}
bool InterfaceType::OneWay() const { return m_oneway; }
void InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
// parcel.writeStrongBinder(v != null ? v.asBinder() : null);
addTo->Add(
new MethodCall(parcel, "writeStrongBinder", 1,
new Ternary(new Comparison(v, "!=", NULL_VALUE),
new MethodCall(v, "asBinder"), NULL_VALUE)));
}
void InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
// v = Interface.asInterface(parcel.readStrongBinder());
addTo->Add(new Assignment(
v, new MethodCall(stub_, "asInterface", 1,
new MethodCall(parcel, "readStrongBinder"))));
}
// ================================================================
GenericListType::GenericListType(const JavaTypeNamespace* types,
const Type* contained_type)
: Type(types, "java.util", "List<" + contained_type->CanonicalName() + ">",
ValidatableType::KIND_BUILT_IN, true, true),
m_contained_type(contained_type),
m_creator(contained_type->CreatorName()) {}
string GenericListType::CreatorName() const {
return "android.os.Parcel.arrayListCreator";
}
string GenericListType::InstantiableName() const {
return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
}
void GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags) const {
if (m_creator == m_types->StringType()->CreatorName()) {
addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
} else if (m_creator == m_types->IBinderType()->CreatorName()) {
addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
} else {
// parcel.writeTypedListXX(arg);
addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
}
}
void GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
if (m_creator == m_types->StringType()->CreatorName()) {
addTo->Add(
new Assignment(v, new MethodCall(parcel, "createStringArrayList", 0)));
} else if (m_creator == m_types->IBinderType()->CreatorName()) {
addTo->Add(
new Assignment(v, new MethodCall(parcel, "createBinderArrayList", 0)));
} else {
// v = _data.readTypedArrayList(XXX.creator);
addTo->Add(
new Assignment(v, new MethodCall(parcel, "createTypedArrayList", 1,
new LiteralExpression(m_creator))));
}
}
void GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable**) const {
if (m_creator == m_types->StringType()->CreatorName()) {
addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
} else if (m_creator == m_types->IBinderType()->CreatorName()) {
addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
} else {
// v = _data.readTypedList(v, XXX.creator);
addTo->Add(new MethodCall(parcel, "readTypedList", 2, v,
new LiteralExpression(m_creator)));
}
}
// ================================================================
ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
: Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN,
false, false) {}
// ================================================================
void JavaTypeNamespace::Init() {
Add(new BasicType(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
m_bool_type = new BooleanType(this);
Add(m_bool_type);
Add(new BasicType(this, "byte", "writeByte", "readByte", "writeByteArray",
"createByteArray", "readByteArray"));
Add(new CharType(this));
m_int_type = new BasicType(this, "int", "writeInt", "readInt",
"writeIntArray", "createIntArray", "readIntArray");
Add(m_int_type);
Add(new BasicType(this, "long", "writeLong", "readLong", "writeLongArray",
"createLongArray", "readLongArray"));
Add(new BasicType(this, "float", "writeFloat", "readFloat", "writeFloatArray",
"createFloatArray", "readFloatArray"));
Add(new BasicType(this, "double", "writeDouble", "readDouble",
"writeDoubleArray", "createDoubleArray",
"readDoubleArray"));
m_string_type = new class StringType(this, "java.lang", "String");
Add(m_string_type);
Add(new class StringType(this, ::android::aidl::kAidlReservedTypePackage,
::android::aidl::kUtf8InCppStringClass));
Add(new Type(this, "java.lang", "Object", ValidatableType::KIND_BUILT_IN,
false, false));
Add(new FileDescriptorType(this));
Add(new CharSequenceType(this));
Add(new MapType(this));
Add(new ListType(this));
m_text_utils_type =
new Type(this, "android.text", "TextUtils",
ValidatableType::KIND_BUILT_IN, false, false);
Add(m_text_utils_type);
m_remote_exception_type = new class RemoteExceptionType(this);
Add(m_remote_exception_type);
m_runtime_exception_type = new class RuntimeExceptionType(this);
Add(m_runtime_exception_type);
m_ibinder_type = new class IBinderType(this);
Add(m_ibinder_type);
m_iinterface_type = new class IInterfaceType(this);
Add(m_iinterface_type);
m_binder_native_type = new class BinderType(this);
Add(m_binder_native_type);
m_binder_proxy_type = new class BinderProxyType(this);
Add(m_binder_proxy_type);
m_parcel_type = new class ParcelType(this);
Add(m_parcel_type);
m_parcelable_interface_type = new class ParcelableInterfaceType(this);
Add(m_parcelable_interface_type);
m_context_type = new class Type(this, "android.content", "Context",
ValidatableType::KIND_BUILT_IN, false, false);
Add(m_context_type);
m_classloader_type = new class ClassLoaderType(this);
Add(m_classloader_type);
NULL_VALUE = new LiteralExpression("null");
THIS_VALUE = new LiteralExpression("this");
SUPER_VALUE = new LiteralExpression("super");
TRUE_VALUE = new LiteralExpression("true");
FALSE_VALUE = new LiteralExpression("false");
}
bool JavaTypeNamespace::AddParcelableType(const AidlParcelable& p,
const std::string& filename) {
Type* type =
new UserDataType(this, p.GetPackage(), p.GetName(), false,
true, filename, p.GetLine());
return Add(type);
}
bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
const std::string& filename) {
// for interfaces, add the stub, proxy, and interface types.
Type* stub = new Type(this, b.GetPackage(),
b.GetName() + ".Stub", ValidatableType::KIND_GENERATED,
false, false, filename, b.GetLine());
Type* proxy = new Type(this, b.GetPackage(),
b.GetName() + ".Stub.Proxy",
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);
bool success = true;
success &= Add(type);
success &= Add(stub);
success &= Add(proxy);
return success;
}
bool JavaTypeNamespace::AddListType(const std::string& contained_type_name) {
const Type* contained_type = FindTypeByCanonicalName(contained_type_name);
if (!contained_type) {
return false;
}
Add(new GenericListType(this, contained_type));
return true;
}
bool JavaTypeNamespace::AddMapType(const string& key_type_name,
const string& value_type_name) {
LOG(ERROR) << "Don't know how to create a Map<K,V> container.";
return false;
}
} // namespace java
} // namespace aidl
} // namespace android