Home | History | Annotate | Download | only in aidl
      1 /*
      2  * Copyright (C) 2015, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "type_java.h"
     18 
     19 #include <sys/types.h>
     20 
     21 #include <android-base/strings.h>
     22 
     23 #include "aidl_language.h"
     24 #include "logging.h"
     25 
     26 using std::string;
     27 using android::base::Split;
     28 using android::base::Join;
     29 using android::base::Trim;
     30 
     31 namespace android {
     32 namespace aidl {
     33 namespace java {
     34 
     35 Expression* NULL_VALUE;
     36 Expression* THIS_VALUE;
     37 Expression* SUPER_VALUE;
     38 Expression* TRUE_VALUE;
     39 Expression* FALSE_VALUE;
     40 
     41 // ================================================================
     42 
     43 Type::Type(const JavaTypeNamespace* types, const string& name, int kind,
     44            bool canWriteToParcel, bool canBeOut)
     45     : Type(types, "", name, kind, canWriteToParcel, canBeOut, "", -1) {}
     46 
     47 Type::Type(const JavaTypeNamespace* types, const string& package,
     48            const string& name, int kind, bool canWriteToParcel,
     49            bool canBeOut, const string& declFile, int declLine)
     50     : ValidatableType(kind, package, name, declFile, declLine),
     51       m_types(types),
     52       m_javaType((package.empty()) ? name : package + "." + name),
     53       m_canWriteToParcel(canWriteToParcel),
     54       m_canBeOut(canBeOut) {
     55 }
     56 
     57 string Type::CreatorName() const { return ""; }
     58 
     59 string Type::InstantiableName() const { return JavaType(); }
     60 
     61 void Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
     62                          int flags) const {
     63   fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn", __FILE__,
     64           __LINE__, m_javaType.c_str());
     65   addTo->Add(new LiteralExpression("/* WriteToParcel error " + m_javaType +
     66                                    " */"));
     67 }
     68 
     69 void Type::CreateFromParcel(StatementBlock* addTo, Variable* v,
     70                             Variable* parcel, Variable**) const {
     71   fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
     72           __LINE__, m_javaType.c_str());
     73   addTo->Add(new LiteralExpression("/* CreateFromParcel error " +
     74                                    m_javaType + " */"));
     75 }
     76 
     77 void Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
     78                           Variable**) const {
     79   fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
     80           __LINE__, m_javaType.c_str());
     81   addTo->Add(new LiteralExpression("/* ReadFromParcel error " +
     82                                    m_javaType + " */"));
     83 }
     84 
     85 Expression* Type::BuildWriteToParcelFlags(int flags) const {
     86   if (flags == 0) {
     87     return new LiteralExpression("0");
     88   }
     89   if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
     90     return new FieldVariable(m_types->ParcelableInterfaceType(),
     91                              "PARCELABLE_WRITE_RETURN_VALUE");
     92   }
     93   return new LiteralExpression("0");
     94 }
     95 
     96 // ================================================================
     97 
     98 BasicType::BasicType(const JavaTypeNamespace* types, const string& name,
     99                      const string& marshallParcel,
    100                      const string& unmarshallParcel,
    101                      const string& writeArrayParcel,
    102                      const string& createArrayParcel,
    103                      const string& readArrayParcel)
    104     : Type(types, name, ValidatableType::KIND_BUILT_IN, true, false),
    105       m_marshallParcel(marshallParcel),
    106       m_unmarshallParcel(unmarshallParcel) {
    107   m_array_type.reset(new BasicArrayType(types, name, writeArrayParcel,
    108                                         createArrayParcel, readArrayParcel));
    109 }
    110 
    111 void BasicType::WriteToParcel(StatementBlock* addTo, Variable* v,
    112                               Variable* parcel, int flags) const {
    113   addTo->Add(new MethodCall(parcel, m_marshallParcel, 1, v));
    114 }
    115 
    116 void BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    117                                  Variable* parcel, Variable**) const {
    118   addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallParcel)));
    119 }
    120 
    121 BasicArrayType::BasicArrayType(const JavaTypeNamespace* types,
    122                                const string& name,
    123                                const string& writeArrayParcel,
    124                                const string& createArrayParcel,
    125                                const string& readArrayParcel)
    126     : Type(types, name, ValidatableType::KIND_BUILT_IN, true, true),
    127       m_writeArrayParcel(writeArrayParcel),
    128       m_createArrayParcel(createArrayParcel),
    129       m_readArrayParcel(readArrayParcel) {}
    130 
    131 
    132 void BasicArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    133                                    Variable* parcel, int flags) const {
    134   addTo->Add(new MethodCall(parcel, m_writeArrayParcel, 1, v));
    135 }
    136 
    137 void BasicArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    138                                       Variable* parcel, Variable**) const {
    139   addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayParcel)));
    140 }
    141 
    142 void BasicArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    143                                     Variable* parcel, Variable**) const {
    144   addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
    145 }
    146 
    147 // ================================================================
    148 
    149 FileDescriptorType::FileDescriptorType(const JavaTypeNamespace* types)
    150     : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
    151            true, false) {
    152     m_array_type.reset(new FileDescriptorArrayType(types));
    153 }
    154 
    155 void FileDescriptorType::WriteToParcel(StatementBlock* addTo, Variable* v,
    156                                        Variable* parcel, int flags) const {
    157   addTo->Add(new MethodCall(parcel, "writeRawFileDescriptor", 1, v));
    158 }
    159 
    160 void FileDescriptorType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    161                                           Variable* parcel, Variable**) const {
    162   addTo->Add(new Assignment(v, new MethodCall(parcel, "readRawFileDescriptor")));
    163 }
    164 
    165 FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
    166     : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
    167            true, true) {}
    168 
    169 void FileDescriptorArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    170                                             Variable* parcel, int flags) const {
    171   addTo->Add(new MethodCall(parcel, "writeRawFileDescriptorArray", 1, v));
    172 }
    173 
    174 void FileDescriptorArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    175                                                Variable* parcel, Variable**) const {
    176   addTo->Add(new Assignment(v, new MethodCall(parcel, "createRawFileDescriptorArray")));
    177 }
    178 
    179 void FileDescriptorArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    180                                              Variable* parcel, Variable**) const {
    181   addTo->Add(new MethodCall(parcel, "readRawFileDescriptorArray", 1, v));
    182 }
    183 
    184 // ================================================================
    185 
    186 BooleanType::BooleanType(const JavaTypeNamespace* types)
    187     : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, false) {
    188     m_array_type.reset(new BooleanArrayType(types));
    189 }
    190 
    191 void BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v,
    192                                 Variable* parcel, int flags) const {
    193   addTo->Add(new MethodCall(
    194       parcel, "writeInt", 1,
    195       new Ternary(v, new LiteralExpression("1"), new LiteralExpression("0"))));
    196 }
    197 
    198 void BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    199                                    Variable* parcel, Variable**) const {
    200   addTo->Add(
    201       new Assignment(v, new Comparison(new LiteralExpression("0"), "!=",
    202                                        new MethodCall(parcel, "readInt"))));
    203 }
    204 
    205 BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
    206     : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, true) {}
    207 
    208 void BooleanArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    209                                      Variable* parcel, int flags) const {
    210   addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
    211 }
    212 
    213 void BooleanArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    214                                         Variable* parcel, Variable**) const {
    215   addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
    216 }
    217 
    218 void BooleanArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    219                                       Variable* parcel, Variable**) const {
    220   addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
    221 }
    222 
    223 // ================================================================
    224 
    225 CharType::CharType(const JavaTypeNamespace* types)
    226     : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, false) {
    227     m_array_type.reset(new CharArrayType(types));
    228 }
    229 
    230 void CharType::WriteToParcel(StatementBlock* addTo, Variable* v,
    231                              Variable* parcel, int flags) const {
    232   addTo->Add(
    233       new MethodCall(parcel, "writeInt", 1, new Cast(m_types->IntType(), v)));
    234 }
    235 
    236 void CharType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    237                                 Variable* parcel, Variable**) const {
    238   addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
    239 }
    240 
    241 CharArrayType::CharArrayType(const JavaTypeNamespace* types)
    242     : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, true) {}
    243 
    244 void CharArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    245                                   Variable* parcel, int flags) const {
    246   addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
    247 }
    248 
    249 void CharArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    250                                      Variable* parcel, Variable**) const {
    251   addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
    252 }
    253 
    254 void CharArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    255                                    Variable* parcel, Variable**) const {
    256   addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
    257 }
    258 
    259 // ================================================================
    260 
    261 StringType::StringType(const JavaTypeNamespace* types,
    262                        const std::string& package,
    263                        const std::string& class_name)
    264     : Type(types, package, class_name,
    265            ValidatableType::KIND_BUILT_IN, true, false) {
    266   m_array_type.reset(new StringArrayType(types));
    267 }
    268 
    269 string StringType::CreatorName() const {
    270   return "android.os.Parcel.STRING_CREATOR";
    271 }
    272 
    273 void StringType::WriteToParcel(StatementBlock* addTo, Variable* v,
    274                                Variable* parcel, int flags) const {
    275   addTo->Add(new MethodCall(parcel, "writeString", 1, v));
    276 }
    277 
    278 void StringType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    279                                   Variable* parcel, Variable**) const {
    280   addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
    281 }
    282 
    283 StringArrayType::StringArrayType(const JavaTypeNamespace* types)
    284     : Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN,
    285            true, true) {}
    286 
    287 string StringArrayType::CreatorName() const {
    288   return "android.os.Parcel.STRING_CREATOR";
    289 }
    290 
    291 void StringArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    292                                     Variable* parcel, int flags) const {
    293   addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
    294 }
    295 
    296 void StringArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    297                                        Variable* parcel, Variable**) const {
    298   addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
    299 }
    300 
    301 void StringArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    302                                      Variable* parcel, Variable**) const {
    303   addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
    304 }
    305 
    306 // ================================================================
    307 
    308 CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
    309     : Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN,
    310            true, false) {}
    311 
    312 string CharSequenceType::CreatorName() const {
    313   return "android.os.Parcel.STRING_CREATOR";
    314 }
    315 
    316 void CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v,
    317                                      Variable* parcel, int flags) const {
    318   // if (v != null) {
    319   //     parcel.writeInt(1);
    320   //     v.writeToParcel(parcel);
    321   // } else {
    322   //     parcel.writeInt(0);
    323   // }
    324   IfStatement* elsepart = new IfStatement();
    325   elsepart->statements->Add(
    326       new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
    327   IfStatement* ifpart = new IfStatement;
    328   ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
    329   ifpart->elseif = elsepart;
    330   ifpart->statements->Add(
    331       new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
    332   ifpart->statements->Add(new MethodCall(m_types->TextUtilsType(),
    333                                          "writeToParcel", 3, v, parcel,
    334                                          BuildWriteToParcelFlags(flags)));
    335 
    336   addTo->Add(ifpart);
    337 }
    338 
    339 void CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    340                                         Variable* parcel, Variable**) const {
    341   // if (0 != parcel.readInt()) {
    342   //     v = TextUtils.createFromParcel(parcel)
    343   // } else {
    344   //     v = null;
    345   // }
    346   IfStatement* elsepart = new IfStatement();
    347   elsepart->statements->Add(new Assignment(v, NULL_VALUE));
    348 
    349   IfStatement* ifpart = new IfStatement();
    350   ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
    351                                       new MethodCall(parcel, "readInt"));
    352   ifpart->elseif = elsepart;
    353   ifpart->statements->Add(new Assignment(
    354       v, new MethodCall(m_types->TextUtilsType(),
    355                         "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
    356 
    357   addTo->Add(ifpart);
    358 }
    359 
    360 // ================================================================
    361 
    362 RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
    363     : Type(types, "android.os", "RemoteException",
    364            ValidatableType::KIND_BUILT_IN, false, false) {}
    365 
    366 void RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
    367                                         Variable* parcel, int flags) const {
    368   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    369 }
    370 
    371 void RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    372                                            Variable* parcel, Variable**) const {
    373   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    374 }
    375 
    376 // ================================================================
    377 
    378 RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
    379     : Type(types, "java.lang", "RuntimeException",
    380            ValidatableType::KIND_BUILT_IN, false, false) {}
    381 
    382 void RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
    383                                          Variable* parcel, int flags) const {
    384   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    385 }
    386 
    387 void RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    388                                             Variable* parcel,
    389                                             Variable**) const {
    390   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    391 }
    392 
    393 // ================================================================
    394 
    395 IBinderType::IBinderType(const JavaTypeNamespace* types)
    396     : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
    397            true, false) {
    398   m_array_type.reset(new IBinderArrayType(types));
    399 }
    400 
    401 void IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
    402                                 Variable* parcel, int flags) const {
    403   addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
    404 }
    405 
    406 void IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    407                                    Variable* parcel, Variable**) const {
    408   addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
    409 }
    410 
    411 IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
    412     : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
    413            true, true) {}
    414 
    415 void IBinderArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    416                                      Variable* parcel, int flags) const {
    417   addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
    418 }
    419 
    420 void IBinderArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    421                                         Variable* parcel, Variable**) const {
    422   addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
    423 }
    424 
    425 void IBinderArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    426                                       Variable* parcel, Variable**) const {
    427   addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
    428 }
    429 
    430 // ================================================================
    431 
    432 IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
    433     : Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN,
    434            false, false) {}
    435 
    436 void IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
    437                                    Variable* parcel, int flags) const {
    438   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    439 }
    440 
    441 void IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    442                                       Variable* parcel, Variable**) const {
    443   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    444 }
    445 
    446 // ================================================================
    447 
    448 BinderType::BinderType(const JavaTypeNamespace* types)
    449     : Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN,
    450            false, false) {}
    451 
    452 void BinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
    453                                Variable* parcel, int flags) const {
    454   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    455 }
    456 
    457 void BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    458                                   Variable* parcel, Variable**) const {
    459   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    460 }
    461 
    462 // ================================================================
    463 
    464 BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
    465     : Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN,
    466            false, false) {}
    467 
    468 void BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v,
    469                                     Variable* parcel, int flags) const {
    470   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    471 }
    472 
    473 void BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    474                                        Variable* parcel, Variable**) const {
    475   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    476 }
    477 
    478 // ================================================================
    479 
    480 ParcelType::ParcelType(const JavaTypeNamespace* types)
    481     : Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN,
    482            false, false) {}
    483 
    484 void ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v,
    485                                Variable* parcel, int flags) const {
    486   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    487 }
    488 
    489 void ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    490                                   Variable* parcel, Variable**) const {
    491   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    492 }
    493 
    494 // ================================================================
    495 
    496 ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
    497     : Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN,
    498            false, false) {}
    499 
    500 void ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
    501                                             Variable* parcel, int flags) const {
    502   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    503 }
    504 
    505 void ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo,
    506                                                Variable* v, Variable* parcel,
    507                                                Variable**) const {
    508   fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
    509 }
    510 
    511 // ================================================================
    512 
    513 MapType::MapType(const JavaTypeNamespace* types)
    514     : Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN,
    515            true, true) {}
    516 
    517 void MapType::WriteToParcel(StatementBlock* addTo, Variable* v,
    518                             Variable* parcel, int flags) const {
    519   addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
    520 }
    521 
    522 static void EnsureClassLoader(StatementBlock* addTo, Variable** cl,
    523                               const JavaTypeNamespace* types) {
    524   // We don't want to look up the class loader once for every
    525   // collection argument, so ensure we do it at most once per method.
    526   if (*cl == NULL) {
    527     *cl = new Variable(types->ClassLoaderType(), "cl");
    528     addTo->Add(new VariableDeclaration(
    529         *cl, new LiteralExpression("this.getClass().getClassLoader()"),
    530         types->ClassLoaderType()));
    531   }
    532 }
    533 
    534 void MapType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    535                                Variable* parcel, Variable** cl) const {
    536   EnsureClassLoader(addTo, cl, m_types);
    537   addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
    538 }
    539 
    540 void MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    541                              Variable* parcel, Variable** cl) const {
    542   EnsureClassLoader(addTo, cl, m_types);
    543   addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
    544 }
    545 
    546 // ================================================================
    547 
    548 ListType::ListType(const JavaTypeNamespace* types)
    549     : Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN,
    550            true, true) {}
    551 
    552 string ListType::InstantiableName() const { return "java.util.ArrayList"; }
    553 
    554 void ListType::WriteToParcel(StatementBlock* addTo, Variable* v,
    555                              Variable* parcel, int flags) const {
    556   addTo->Add(new MethodCall(parcel, "writeList", 1, v));
    557 }
    558 
    559 void ListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    560                                 Variable* parcel, Variable** cl) const {
    561   EnsureClassLoader(addTo, cl, m_types);
    562   addTo->Add(
    563       new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
    564 }
    565 
    566 void ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    567                               Variable* parcel, Variable** cl) const {
    568   EnsureClassLoader(addTo, cl, m_types);
    569   addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
    570 }
    571 
    572 // ================================================================
    573 
    574 UserDataType::UserDataType(const JavaTypeNamespace* types,
    575                            const string& package, const string& name,
    576                            bool builtIn, bool canWriteToParcel,
    577                            const string& declFile, int declLine)
    578     : Type(types, package, name,
    579            builtIn ? ValidatableType::KIND_BUILT_IN
    580                    : ValidatableType::KIND_PARCELABLE,
    581            canWriteToParcel, true, declFile, declLine) {
    582   m_array_type.reset(new UserDataArrayType(types, package, name, builtIn,
    583                                            canWriteToParcel, declFile,
    584                                            declLine));
    585 }
    586 
    587 string UserDataType::CreatorName() const {
    588   return JavaType() + ".CREATOR";
    589 }
    590 
    591 void UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v,
    592                                  Variable* parcel, int flags) const {
    593   // if (v != null) {
    594   //     parcel.writeInt(1);
    595   //     v.writeToParcel(parcel);
    596   // } else {
    597   //     parcel.writeInt(0);
    598   // }
    599   IfStatement* elsepart = new IfStatement();
    600   elsepart->statements->Add(
    601       new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
    602   IfStatement* ifpart = new IfStatement;
    603   ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
    604   ifpart->elseif = elsepart;
    605   ifpart->statements->Add(
    606       new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
    607   ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, parcel,
    608                                          BuildWriteToParcelFlags(flags)));
    609 
    610   addTo->Add(ifpart);
    611 }
    612 
    613 void UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    614                                     Variable* parcel, Variable**) const {
    615   // if (0 != parcel.readInt()) {
    616   //     v = CLASS.CREATOR.createFromParcel(parcel)
    617   // } else {
    618   //     v = null;
    619   // }
    620   IfStatement* elsepart = new IfStatement();
    621   elsepart->statements->Add(new Assignment(v, NULL_VALUE));
    622 
    623   IfStatement* ifpart = new IfStatement();
    624   ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
    625                                       new MethodCall(parcel, "readInt"));
    626   ifpart->elseif = elsepart;
    627   ifpart->statements->Add(new Assignment(
    628       v, new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
    629 
    630   addTo->Add(ifpart);
    631 }
    632 
    633 void UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    634                                   Variable* parcel, Variable**) const {
    635   // TODO: really, we don't need to have this extra check, but we
    636   // don't have two separate marshalling code paths
    637   // if (0 != parcel.readInt()) {
    638   //     v.readFromParcel(parcel)
    639   // }
    640   IfStatement* ifpart = new IfStatement();
    641   ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
    642                                       new MethodCall(parcel, "readInt"));
    643   ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
    644   addTo->Add(ifpart);
    645 }
    646 
    647 UserDataArrayType::UserDataArrayType(const JavaTypeNamespace* types,
    648                            const string& package, const string& name,
    649                            bool builtIn, bool canWriteToParcel,
    650                            const string& declFile, int declLine)
    651     : Type(types, package, name,
    652            builtIn ? ValidatableType::KIND_BUILT_IN
    653                    : ValidatableType::KIND_PARCELABLE,
    654            canWriteToParcel, true, declFile, declLine) {}
    655 
    656 string UserDataArrayType::CreatorName() const {
    657   return JavaType() + ".CREATOR";
    658 }
    659 
    660 void UserDataArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
    661                                       Variable* parcel, int flags) const {
    662   addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
    663                             BuildWriteToParcelFlags(flags)));
    664 }
    665 
    666 void UserDataArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    667                                          Variable* parcel, Variable**) const {
    668   string creator = v->type->JavaType() + ".CREATOR";
    669   addTo->Add(new Assignment(v, new MethodCall(parcel, "createTypedArray", 1,
    670                                               new LiteralExpression(creator))));
    671 }
    672 
    673 void UserDataArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    674                                        Variable* parcel, Variable**) const {
    675   string creator = v->type->JavaType() + ".CREATOR";
    676   addTo->Add(new MethodCall(parcel, "readTypedArray", 2, v,
    677                             new LiteralExpression(creator)));
    678 }
    679 
    680 // ================================================================
    681 
    682 InterfaceType::InterfaceType(const JavaTypeNamespace* types,
    683                              const string& package, const string& name,
    684                              bool builtIn, bool oneway, const string& declFile,
    685                              int declLine, const Type* stub, const Type* proxy)
    686     : Type(types, package, name, builtIn ? ValidatableType::KIND_BUILT_IN
    687                                          : ValidatableType::KIND_INTERFACE,
    688            true, false, declFile, declLine),
    689       m_oneway(oneway),
    690       stub_(stub),
    691       proxy_(proxy) {}
    692 
    693 bool InterfaceType::OneWay() const { return m_oneway; }
    694 
    695 void InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
    696                                   Variable* parcel, int flags) const {
    697   // parcel.writeStrongBinder(v != null ? v.asBinder() : null);
    698   addTo->Add(
    699       new MethodCall(parcel, "writeStrongBinder", 1,
    700                      new Ternary(new Comparison(v, "!=", NULL_VALUE),
    701                                  new MethodCall(v, "asBinder"), NULL_VALUE)));
    702 }
    703 
    704 void InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    705                                      Variable* parcel, Variable**) const {
    706   // v = Interface.asInterface(parcel.readStrongBinder());
    707   addTo->Add(new Assignment(
    708       v, new MethodCall(stub_, "asInterface", 1,
    709                         new MethodCall(parcel, "readStrongBinder"))));
    710 }
    711 
    712 // ================================================================
    713 
    714 GenericListType::GenericListType(const JavaTypeNamespace* types,
    715                                  const Type* contained_type)
    716     : Type(types, "java.util", "List<" + contained_type->CanonicalName() + ">",
    717            ValidatableType::KIND_BUILT_IN, true, true),
    718       m_contained_type(contained_type),
    719       m_creator(contained_type->CreatorName()) {}
    720 
    721 string GenericListType::CreatorName() const {
    722   return "android.os.Parcel.arrayListCreator";
    723 }
    724 
    725 string GenericListType::InstantiableName() const {
    726   return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
    727 }
    728 
    729 void GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v,
    730                                     Variable* parcel, int flags) const {
    731   if (m_creator == m_types->StringType()->CreatorName()) {
    732     addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
    733   } else if (m_creator == m_types->IBinderType()->CreatorName()) {
    734     addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
    735   } else {
    736     // parcel.writeTypedListXX(arg);
    737     addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
    738   }
    739 }
    740 
    741 void GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
    742                                        Variable* parcel, Variable**) const {
    743   if (m_creator == m_types->StringType()->CreatorName()) {
    744     addTo->Add(
    745         new Assignment(v, new MethodCall(parcel, "createStringArrayList", 0)));
    746   } else if (m_creator == m_types->IBinderType()->CreatorName()) {
    747     addTo->Add(
    748         new Assignment(v, new MethodCall(parcel, "createBinderArrayList", 0)));
    749   } else {
    750     // v = _data.readTypedArrayList(XXX.creator);
    751     addTo->Add(
    752         new Assignment(v, new MethodCall(parcel, "createTypedArrayList", 1,
    753                                          new LiteralExpression(m_creator))));
    754   }
    755 }
    756 
    757 void GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
    758                                      Variable* parcel, Variable**) const {
    759   if (m_creator == m_types->StringType()->CreatorName()) {
    760     addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
    761   } else if (m_creator == m_types->IBinderType()->CreatorName()) {
    762     addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
    763   } else {
    764     // v = _data.readTypedList(v, XXX.creator);
    765     addTo->Add(new MethodCall(parcel, "readTypedList", 2, v,
    766                               new LiteralExpression(m_creator)));
    767   }
    768 }
    769 
    770 // ================================================================
    771 
    772 ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
    773     : Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN,
    774            false, false) {}
    775 
    776 // ================================================================
    777 
    778 void JavaTypeNamespace::Init() {
    779   Add(new BasicType(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
    780 
    781   m_bool_type = new BooleanType(this);
    782   Add(m_bool_type);
    783 
    784   Add(new BasicType(this, "byte", "writeByte", "readByte", "writeByteArray",
    785                     "createByteArray", "readByteArray"));
    786 
    787   Add(new CharType(this));
    788 
    789   m_int_type = new BasicType(this, "int", "writeInt", "readInt",
    790                              "writeIntArray", "createIntArray", "readIntArray");
    791   Add(m_int_type);
    792 
    793   Add(new BasicType(this, "long", "writeLong", "readLong", "writeLongArray",
    794                     "createLongArray", "readLongArray"));
    795 
    796   Add(new BasicType(this, "float", "writeFloat", "readFloat", "writeFloatArray",
    797                     "createFloatArray", "readFloatArray"));
    798 
    799   Add(new BasicType(this, "double", "writeDouble", "readDouble",
    800                     "writeDoubleArray", "createDoubleArray",
    801                     "readDoubleArray"));
    802 
    803   m_string_type = new class StringType(this, "java.lang", "String");
    804   Add(m_string_type);
    805   Add(new class StringType(this, ::android::aidl::kAidlReservedTypePackage,
    806                            ::android::aidl::kUtf8InCppStringClass));
    807 
    808   Add(new Type(this, "java.lang", "Object", ValidatableType::KIND_BUILT_IN,
    809                false, false));
    810 
    811   Add(new FileDescriptorType(this));
    812 
    813   Add(new CharSequenceType(this));
    814 
    815   Add(new MapType(this));
    816 
    817   Add(new ListType(this));
    818 
    819   m_text_utils_type =
    820       new Type(this, "android.text", "TextUtils",
    821                ValidatableType::KIND_BUILT_IN, false, false);
    822   Add(m_text_utils_type);
    823 
    824   m_remote_exception_type = new class RemoteExceptionType(this);
    825   Add(m_remote_exception_type);
    826 
    827   m_runtime_exception_type = new class RuntimeExceptionType(this);
    828   Add(m_runtime_exception_type);
    829 
    830   m_ibinder_type = new class IBinderType(this);
    831   Add(m_ibinder_type);
    832 
    833   m_iinterface_type = new class IInterfaceType(this);
    834   Add(m_iinterface_type);
    835 
    836   m_binder_native_type = new class BinderType(this);
    837   Add(m_binder_native_type);
    838 
    839   m_binder_proxy_type = new class BinderProxyType(this);
    840   Add(m_binder_proxy_type);
    841 
    842   m_parcel_type = new class ParcelType(this);
    843   Add(m_parcel_type);
    844 
    845   m_parcelable_interface_type = new class ParcelableInterfaceType(this);
    846   Add(m_parcelable_interface_type);
    847 
    848   m_context_type = new class Type(this, "android.content", "Context",
    849                                   ValidatableType::KIND_BUILT_IN, false, false);
    850   Add(m_context_type);
    851 
    852   m_classloader_type = new class ClassLoaderType(this);
    853   Add(m_classloader_type);
    854 
    855   NULL_VALUE = new LiteralExpression("null");
    856   THIS_VALUE = new LiteralExpression("this");
    857   SUPER_VALUE = new LiteralExpression("super");
    858   TRUE_VALUE = new LiteralExpression("true");
    859   FALSE_VALUE = new LiteralExpression("false");
    860 }
    861 
    862 bool JavaTypeNamespace::AddParcelableType(const AidlParcelable& p,
    863                                           const std::string& filename) {
    864   Type* type =
    865       new UserDataType(this, p.GetPackage(), p.GetName(), false,
    866                        true, filename, p.GetLine());
    867   return Add(type);
    868 }
    869 
    870 bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
    871                                       const std::string& filename) {
    872   // for interfaces, add the stub, proxy, and interface types.
    873   Type* stub = new Type(this, b.GetPackage(),
    874                         b.GetName() + ".Stub", ValidatableType::KIND_GENERATED,
    875                         false, false, filename, b.GetLine());
    876   Type* proxy = new Type(this, b.GetPackage(),
    877                          b.GetName() + ".Stub.Proxy",
    878                          ValidatableType::KIND_GENERATED,
    879                          false, false, filename, b.GetLine());
    880   Type* type =
    881       new InterfaceType(this, b.GetPackage(), b.GetName(), false,
    882                         b.IsOneway(), filename, b.GetLine(), stub, proxy);
    883 
    884   bool success = true;
    885   success &= Add(type);
    886   success &= Add(stub);
    887   success &= Add(proxy);
    888   return success;
    889 }
    890 
    891 bool JavaTypeNamespace::AddListType(const std::string& contained_type_name) {
    892   const Type* contained_type = FindTypeByCanonicalName(contained_type_name);
    893   if (!contained_type) {
    894     return false;
    895   }
    896   Add(new GenericListType(this, contained_type));
    897   return true;
    898 }
    899 
    900 bool JavaTypeNamespace::AddMapType(const string& key_type_name,
    901                                    const string& value_type_name) {
    902   LOG(ERROR) << "Don't know how to create a Map<K,V> container.";
    903   return false;
    904 }
    905 
    906 }  // namespace java
    907 }  // namespace aidl
    908 }  // namespace android
    909