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