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 
Type(const JavaTypeNamespace * types,const string & name,int kind,bool canWriteToParcel,bool canBeOut)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 
Type(const JavaTypeNamespace * types,const string & package,const string & name,int kind,bool canWriteToParcel,bool canBeOut,const string & declFile,int declLine)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 
CreatorName() const57 string Type::CreatorName() const { return ""; }
58 
InstantiableName() const59 string Type::InstantiableName() const { return JavaType(); }
60 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const61 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const69 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const77 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 
BuildWriteToParcelFlags(int flags) const85 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 
BasicType(const JavaTypeNamespace * types,const string & name,const string & marshallParcel,const string & unmarshallParcel,const string & writeArrayParcel,const string & createArrayParcel,const string & readArrayParcel)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 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const111 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const116 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 
BasicArrayType(const JavaTypeNamespace * types,const string & name,const string & writeArrayParcel,const string & createArrayParcel,const string & readArrayParcel)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 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const132 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const137 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const142 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 
FileDescriptorType(const JavaTypeNamespace * types)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 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const155 void FileDescriptorType::WriteToParcel(StatementBlock* addTo, Variable* v,
156                                        Variable* parcel, int flags) const {
157   addTo->Add(new MethodCall(parcel, "writeRawFileDescriptor", 1, v));
158 }
159 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const160 void FileDescriptorType::CreateFromParcel(StatementBlock* addTo, Variable* v,
161                                           Variable* parcel, Variable**) const {
162   addTo->Add(new Assignment(v, new MethodCall(parcel, "readRawFileDescriptor")));
163 }
164 
FileDescriptorArrayType(const JavaTypeNamespace * types)165 FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
166     : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
167            true, true) {}
168 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const169 void FileDescriptorArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
170                                             Variable* parcel, int flags) const {
171   addTo->Add(new MethodCall(parcel, "writeRawFileDescriptorArray", 1, v));
172 }
173 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const174 void FileDescriptorArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
175                                                Variable* parcel, Variable**) const {
176   addTo->Add(new Assignment(v, new MethodCall(parcel, "createRawFileDescriptorArray")));
177 }
178 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const179 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 
BooleanType(const JavaTypeNamespace * types)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 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const191 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const198 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 
BooleanArrayType(const JavaTypeNamespace * types)205 BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
206     : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, true) {}
207 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const208 void BooleanArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
209                                      Variable* parcel, int flags) const {
210   addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
211 }
212 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const213 void BooleanArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
214                                         Variable* parcel, Variable**) const {
215   addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
216 }
217 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const218 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 
CharType(const JavaTypeNamespace * types)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 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const230 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const236 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 
CharArrayType(const JavaTypeNamespace * types)241 CharArrayType::CharArrayType(const JavaTypeNamespace* types)
242     : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, true) {}
243 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const244 void CharArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
245                                   Variable* parcel, int flags) const {
246   addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
247 }
248 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const249 void CharArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
250                                      Variable* parcel, Variable**) const {
251   addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
252 }
253 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const254 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 
StringType(const JavaTypeNamespace * types,const std::string & package,const std::string & class_name)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 
CreatorName() const269 string StringType::CreatorName() const {
270   return "android.os.Parcel.STRING_CREATOR";
271 }
272 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const273 void StringType::WriteToParcel(StatementBlock* addTo, Variable* v,
274                                Variable* parcel, int flags) const {
275   addTo->Add(new MethodCall(parcel, "writeString", 1, v));
276 }
277 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const278 void StringType::CreateFromParcel(StatementBlock* addTo, Variable* v,
279                                   Variable* parcel, Variable**) const {
280   addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
281 }
282 
StringArrayType(const JavaTypeNamespace * types)283 StringArrayType::StringArrayType(const JavaTypeNamespace* types)
284     : Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN,
285            true, true) {}
286 
CreatorName() const287 string StringArrayType::CreatorName() const {
288   return "android.os.Parcel.STRING_CREATOR";
289 }
290 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const291 void StringArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
292                                     Variable* parcel, int flags) const {
293   addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
294 }
295 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const296 void StringArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
297                                        Variable* parcel, Variable**) const {
298   addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
299 }
300 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const301 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 
CharSequenceType(const JavaTypeNamespace * types)308 CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
309     : Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN,
310            true, false) {}
311 
CreatorName() const312 string CharSequenceType::CreatorName() const {
313   return "android.os.Parcel.STRING_CREATOR";
314 }
315 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const316 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const339 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 
RemoteExceptionType(const JavaTypeNamespace * types)362 RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
363     : Type(types, "android.os", "RemoteException",
364            ValidatableType::KIND_BUILT_IN, false, false) {}
365 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const366 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const371 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 
RuntimeExceptionType(const JavaTypeNamespace * types)378 RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
379     : Type(types, "java.lang", "RuntimeException",
380            ValidatableType::KIND_BUILT_IN, false, false) {}
381 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const382 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const387 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 
IBinderType(const JavaTypeNamespace * types)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 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const401 void IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
402                                 Variable* parcel, int flags) const {
403   addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
404 }
405 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const406 void IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
407                                    Variable* parcel, Variable**) const {
408   addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
409 }
410 
IBinderArrayType(const JavaTypeNamespace * types)411 IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
412     : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
413            true, true) {}
414 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const415 void IBinderArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
416                                      Variable* parcel, int flags) const {
417   addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
418 }
419 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const420 void IBinderArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
421                                         Variable* parcel, Variable**) const {
422   addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
423 }
424 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const425 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 
IInterfaceType(const JavaTypeNamespace * types)432 IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
433     : Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN,
434            false, false) {}
435 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const436 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const441 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 
BinderType(const JavaTypeNamespace * types)448 BinderType::BinderType(const JavaTypeNamespace* types)
449     : Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN,
450            false, false) {}
451 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const452 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const457 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 
BinderProxyType(const JavaTypeNamespace * types)464 BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
465     : Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN,
466            false, false) {}
467 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const468 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const473 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 
ParcelType(const JavaTypeNamespace * types)480 ParcelType::ParcelType(const JavaTypeNamespace* types)
481     : Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN,
482            false, false) {}
483 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const484 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const489 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 
ParcelableInterfaceType(const JavaTypeNamespace * types)496 ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
497     : Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN,
498            false, false) {}
499 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const500 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const505 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 
MapType(const JavaTypeNamespace * types)513 MapType::MapType(const JavaTypeNamespace* types)
514     : Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN,
515            true, true) {}
516 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const517 void MapType::WriteToParcel(StatementBlock* addTo, Variable* v,
518                             Variable* parcel, int flags) const {
519   addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
520 }
521 
EnsureClassLoader(StatementBlock * addTo,Variable ** cl,const JavaTypeNamespace * types)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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable ** cl) const534 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable ** cl) const540 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 
ListType(const JavaTypeNamespace * types)548 ListType::ListType(const JavaTypeNamespace* types)
549     : Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN,
550            true, true) {}
551 
InstantiableName() const552 string ListType::InstantiableName() const { return "java.util.ArrayList"; }
553 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const554 void ListType::WriteToParcel(StatementBlock* addTo, Variable* v,
555                              Variable* parcel, int flags) const {
556   addTo->Add(new MethodCall(parcel, "writeList", 1, v));
557 }
558 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable ** cl) const559 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable ** cl) const566 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 
UserDataType(const JavaTypeNamespace * types,const string & package,const string & name,bool builtIn,bool canWriteToParcel,const string & declFile,int declLine)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 
CreatorName() const587 string UserDataType::CreatorName() const {
588   return JavaType() + ".CREATOR";
589 }
590 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const591 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const613 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const633 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 
UserDataArrayType(const JavaTypeNamespace * types,const string & package,const string & name,bool builtIn,bool canWriteToParcel,const string & declFile,int declLine)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 
CreatorName() const656 string UserDataArrayType::CreatorName() const {
657   return JavaType() + ".CREATOR";
658 }
659 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const660 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const666 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const673 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 
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)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 
OneWay() const693 bool InterfaceType::OneWay() const { return m_oneway; }
694 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const695 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const704 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 
GenericListType(const JavaTypeNamespace * types,const Type * contained_type)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 
CreatorName() const721 string GenericListType::CreatorName() const {
722   return "android.os.Parcel.arrayListCreator";
723 }
724 
InstantiableName() const725 string GenericListType::InstantiableName() const {
726   return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
727 }
728 
WriteToParcel(StatementBlock * addTo,Variable * v,Variable * parcel,int flags) const729 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 
CreateFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const741 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 
ReadFromParcel(StatementBlock * addTo,Variable * v,Variable * parcel,Variable **) const757 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 
ClassLoaderType(const JavaTypeNamespace * types)772 ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
773     : Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN,
774            false, false) {}
775 
776 // ================================================================
777 
Init()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 
AddParcelableType(const AidlParcelable & p,const std::string & filename)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 
AddBinderType(const AidlInterface & b,const std::string & filename)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 
AddListType(const std::string & contained_type_name)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 
AddMapType(const string & key_type_name,const string & value_type_name)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