1f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskipackage android.content.pm;
2f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
3f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport android.os.Parcel;
4f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport android.os.Parcelable;
5f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport junit.framework.TestCase;
6f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
7f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport java.util.ArrayList;
8f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport java.util.List;
9f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
10f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskipublic class ParceledListSliceTest extends TestCase {
11f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
12f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    public void testSmallList() throws Exception {
13f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        final int objectCount = 100;
1448c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer        List<SmallObject> list = new ArrayList<SmallObject>();
15f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        for (int i = 0; i < objectCount; i++) {
16f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            list.add(new SmallObject(i * 2, (i * 2) + 1));
17f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
18f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
19f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        ParceledListSlice<SmallObject> slice;
20f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
21f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        Parcel parcel = Parcel.obtain();
22f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        try {
2348c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer            parcel.writeParcelable(new ParceledListSlice<SmallObject>(list), 0);
24f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            parcel.setDataPosition(0);
25f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            slice = parcel.readParcelable(getClass().getClassLoader());
26f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        } finally {
27f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            parcel.recycle();
28f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
29f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
30f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        assertNotNull(slice);
31f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        assertNotNull(slice.getList());
32f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        assertEquals(objectCount, slice.getList().size());
33f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
34f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        for (int i = 0; i < objectCount; i++) {
35f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals(i * 2, slice.getList().get(i).mFieldA);
36f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals((i * 2) + 1, slice.getList().get(i).mFieldB);
37f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
38f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
39f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
40f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    private static int measureLargeObject() {
41f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        Parcel p = Parcel.obtain();
42f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        try {
43f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            new LargeObject(0, 0, 0, 0, 0).writeToParcel(p, 0);
44f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            return p.dataPosition();
45f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        } finally {
46f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            p.recycle();
47f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
48f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
49f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
50f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    /**
51f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * Test that when the list is large, the data is successfully parceled
52f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * and unparceled (the implementation will send pieces of the list in
53f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * separate round-trips to avoid the IPC limit).
54f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     */
55f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    public void testLargeList() throws Exception {
56f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        final int thresholdBytes = 256 * 1024;
57f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        final int objectCount = thresholdBytes / measureLargeObject();
58f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
5948c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer        List<LargeObject> list = new ArrayList<LargeObject>();
60f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        for (int i = 0; i < objectCount; i++) {
61f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            list.add(new LargeObject(
62f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    i * 5,
63f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    (i * 5) + 1,
64f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    (i * 5) + 2,
65f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    (i * 5) + 3,
66f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    (i * 5) + 4
67f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            ));
68f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
69f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
70f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        ParceledListSlice<LargeObject> slice;
71f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
72f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        Parcel parcel = Parcel.obtain();
73f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        try {
7448c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer            parcel.writeParcelable(new ParceledListSlice<LargeObject>(list), 0);
75f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            parcel.setDataPosition(0);
76f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            slice = parcel.readParcelable(getClass().getClassLoader());
77f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        } finally {
78f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            parcel.recycle();
79f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
80f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
81f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        assertNotNull(slice);
82f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        assertNotNull(slice.getList());
83f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        assertEquals(objectCount, slice.getList().size());
84f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
85f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        for (int i = 0; i < objectCount; i++) {
86f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals(i * 5, slice.getList().get(i).mFieldA);
87f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals((i * 5) + 1, slice.getList().get(i).mFieldB);
88f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals((i * 5) + 2, slice.getList().get(i).mFieldC);
89f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals((i * 5) + 3, slice.getList().get(i).mFieldD);
90f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            assertEquals((i * 5) + 4, slice.getList().get(i).mFieldE);
91f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
92f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
93f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
94f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    /**
95f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * Test that only homogeneous elements may be unparceled.
96f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     */
97f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    public void testHomogeneousElements() throws Exception {
9848c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer        List<BaseObject> list = new ArrayList<BaseObject>();
99f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        list.add(new LargeObject(0, 1, 2, 3, 4));
100f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        list.add(new SmallObject(5, 6));
101f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        list.add(new SmallObject(7, 8));
102f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
103f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        Parcel parcel = Parcel.obtain();
104f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        try {
105f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            writeEvilParceledListSlice(parcel, list);
106f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            parcel.setDataPosition(0);
107f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            try {
108f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                ParceledListSlice.CREATOR.createFromParcel(parcel, getClass().getClassLoader());
109f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                assertTrue("Unparceled heterogeneous ParceledListSlice", false);
110f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            } catch (IllegalArgumentException e) {
111f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                // Success, we're not allowed to process heterogeneous
112f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                // elements in a ParceledListSlice.
113f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
114f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        } finally {
115f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            parcel.recycle();
116f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
117f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
118f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
119f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    /**
120f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * Write a ParcelableListSlice that uses the BaseObject base class as the Creator.
121f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * This is dangerous, as it may affect how the data is unparceled, then later parceled
122f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     * by the system, leading to a self-modifying data security vulnerability.
123f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski     */
124f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    private static <T extends BaseObject> void writeEvilParceledListSlice(Parcel dest, List<T> list) {
125f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        final int listCount = list.size();
126f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
127f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        // Number of items.
128f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        dest.writeInt(listCount);
129f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
130f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        // The type/creator to use when unparceling. Here we use the base class
131f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        // to simulate an attack on ParceledListSlice.
132f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        dest.writeString(BaseObject.class.getName());
133f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
134f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        for (int i = 0; i < listCount; i++) {
135f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            // 1 means the item is present.
136f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(1);
137f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            list.get(i).writeToParcel(dest, 0);
138f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
139f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
140f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
141f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    public abstract static class BaseObject implements Parcelable {
142f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        protected static final int TYPE_SMALL = 0;
143f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        protected static final int TYPE_LARGE = 1;
144f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
145f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        protected void writeToParcel(Parcel dest, int flags, int type) {
146f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(type);
147f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
148f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
149f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        @Override
150f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int describeContents() {
151f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            return 0;
152f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
153f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
154f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        /**
155f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski         * This is *REALLY* bad, but we're doing it in the test to ensure that we handle
156f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski         * the possible exploit when unparceling an object with the BaseObject written as
157f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski         * Creator.
158f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski         */
159f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public static final Creator<BaseObject> CREATOR = new Creator<BaseObject>() {
160f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            @Override
161f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            public BaseObject createFromParcel(Parcel source) {
162f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                switch (source.readInt()) {
163f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    case TYPE_SMALL:
164f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                        return SmallObject.createFromParcelBody(source);
165f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    case TYPE_LARGE:
166f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                        return LargeObject.createFromParcelBody(source);
167f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    default:
168f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                        throw new IllegalArgumentException("Unknown type");
169f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                }
170f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
171f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
172f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            @Override
173f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            public BaseObject[] newArray(int size) {
174f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                return new BaseObject[size];
175f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
176f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        };
177f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
178f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
179f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    public static class SmallObject extends BaseObject {
180f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldA;
181f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldB;
182f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
183f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public SmallObject(int a, int b) {
184f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldA = a;
185f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldB = b;
186f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
187f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
188f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        @Override
189f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public void writeToParcel(Parcel dest, int flags) {
190f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            super.writeToParcel(dest, flags, TYPE_SMALL);
191f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldA);
192f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldB);
193f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
194f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
195f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public static SmallObject createFromParcelBody(Parcel source) {
196f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            return new SmallObject(source.readInt(), source.readInt());
197f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
198f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
199f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public static final Creator<SmallObject> CREATOR = new Creator<SmallObject>() {
200f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            @Override
201f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            public SmallObject createFromParcel(Parcel source) {
202f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                // Consume the type (as it is always written out).
203f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                source.readInt();
204f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                return createFromParcelBody(source);
205f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
206f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
207f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            @Override
208f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            public SmallObject[] newArray(int size) {
209f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                return new SmallObject[size];
210f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
211f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        };
212f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
213f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
214f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    public static class LargeObject extends BaseObject {
215f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldA;
216f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldB;
217f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldC;
218f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldD;
219f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public int mFieldE;
220f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
221f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public LargeObject(int a, int b, int c, int d, int e) {
222f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldA = a;
223f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldB = b;
224f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldC = c;
225f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldD = d;
226f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            mFieldE = e;
227f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
228f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
229f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        @Override
230f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public void writeToParcel(Parcel dest, int flags) {
231f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            super.writeToParcel(dest, flags, TYPE_LARGE);
232f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldA);
233f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldB);
234f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldC);
235f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldD);
236f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            dest.writeInt(mFieldE);
237f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
238f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
239f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public static LargeObject createFromParcelBody(Parcel source) {
240f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            return new LargeObject(
241f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    source.readInt(),
242f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    source.readInt(),
243f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    source.readInt(),
244f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    source.readInt(),
245f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                    source.readInt()
246f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            );
247f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        }
248f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
249f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        public static final Creator<LargeObject> CREATOR = new Creator<LargeObject>() {
250f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            @Override
251f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            public LargeObject createFromParcel(Parcel source) {
252f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                // Consume the type (as it is always written out).
253f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                source.readInt();
254f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                return createFromParcelBody(source);
255f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
256f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski
257f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            @Override
258f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            public LargeObject[] newArray(int size) {
259f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski                return new LargeObject[size];
260f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski            }
261f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski        };
262f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski    }
263f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski}
264