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