1f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskipackage android.content.pm; 2f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 3f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport android.os.Parcel; 4f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport android.os.Parcelable; 5bdbde55592792efe350acd6a46733f439f6a3f3dAurimas Liutikasimport android.support.test.filters.LargeTest; 62682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 7f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport junit.framework.TestCase; 8f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 9f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport java.util.ArrayList; 102682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaruimport java.util.Collections; 11f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskiimport java.util.List; 12f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 13bdbde55592792efe350acd6a46733f439f6a3f3dAurimas Liutikas@LargeTest 14f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinskipublic class ParceledListSliceTest extends TestCase { 15f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 16f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public void testSmallList() throws Exception { 17f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski final int objectCount = 100; 1848c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer List<SmallObject> list = new ArrayList<SmallObject>(); 19f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski for (int i = 0; i < objectCount; i++) { 20f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski list.add(new SmallObject(i * 2, (i * 2) + 1)); 21f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 22f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 23f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski ParceledListSlice<SmallObject> slice; 24f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 25f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski Parcel parcel = Parcel.obtain(); 26f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski try { 2748c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer parcel.writeParcelable(new ParceledListSlice<SmallObject>(list), 0); 28f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski parcel.setDataPosition(0); 29f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski slice = parcel.readParcelable(getClass().getClassLoader()); 30f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } finally { 31f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski parcel.recycle(); 32f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 33f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 34f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertNotNull(slice); 35f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertNotNull(slice.getList()); 36f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals(objectCount, slice.getList().size()); 37f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 38f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski for (int i = 0; i < objectCount; i++) { 39f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals(i * 2, slice.getList().get(i).mFieldA); 40f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals((i * 2) + 1, slice.getList().get(i).mFieldB); 41f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 42f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 43f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 44f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski private static int measureLargeObject() { 45f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski Parcel p = Parcel.obtain(); 46f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski try { 47f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski new LargeObject(0, 0, 0, 0, 0).writeToParcel(p, 0); 48f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return p.dataPosition(); 49f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } finally { 50f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski p.recycle(); 51f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 52f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 53f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 54f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski /** 55f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * Test that when the list is large, the data is successfully parceled 56f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * and unparceled (the implementation will send pieces of the list in 57f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * separate round-trips to avoid the IPC limit). 58f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski */ 59f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public void testLargeList() throws Exception { 60f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski final int thresholdBytes = 256 * 1024; 61f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski final int objectCount = thresholdBytes / measureLargeObject(); 62f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 6348c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer List<LargeObject> list = new ArrayList<LargeObject>(); 64f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski for (int i = 0; i < objectCount; i++) { 65f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski list.add(new LargeObject( 66f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski i * 5, 67f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski (i * 5) + 1, 68f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski (i * 5) + 2, 69f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski (i * 5) + 3, 70f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski (i * 5) + 4 71f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski )); 72f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 73f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 74f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski ParceledListSlice<LargeObject> slice; 75f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 76f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski Parcel parcel = Parcel.obtain(); 77f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski try { 7848c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer parcel.writeParcelable(new ParceledListSlice<LargeObject>(list), 0); 79f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski parcel.setDataPosition(0); 80f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski slice = parcel.readParcelable(getClass().getClassLoader()); 81f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } finally { 82f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski parcel.recycle(); 83f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 84f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 85f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertNotNull(slice); 86f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertNotNull(slice.getList()); 87f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals(objectCount, slice.getList().size()); 88f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 89f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski for (int i = 0; i < objectCount; i++) { 90f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals(i * 5, slice.getList().get(i).mFieldA); 91f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals((i * 5) + 1, slice.getList().get(i).mFieldB); 92f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals((i * 5) + 2, slice.getList().get(i).mFieldC); 93f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals((i * 5) + 3, slice.getList().get(i).mFieldD); 94f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertEquals((i * 5) + 4, slice.getList().get(i).mFieldE); 95f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 96f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 97f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 982682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru private void sendParcelStringList(List<String> list) { 99abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee StringParceledListSlice slice; 100abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee Parcel parcel = Parcel.obtain(); 1012682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 102abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee try { 103abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee parcel.writeParcelable(new StringParceledListSlice(list), 0); 104abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee parcel.setDataPosition(0); 105abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee slice = parcel.readParcelable(getClass().getClassLoader()); 106abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee } finally { 107abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee parcel.recycle(); 108abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee } 109abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee 110abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee assertNotNull(slice); 111abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee assertNotNull(slice.getList()); 112abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee assertEquals(list, slice.getList()); 113abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee } 114abaa0695c5361b36a7a2cdbe87c77bf60be20af7Robin Lee 1152682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru public void testStringList() throws Exception { 1162682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru final int objectCount = 400; 1172682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru List<String> list = new ArrayList<String>(); 1182682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru for (long i = 0; i < objectCount; i++) { 1192682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru list.add(Long.toString(i * (6 - i))); 1202682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru } 1212682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 1222682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru sendParcelStringList(list); 1232682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru } 1242682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 1252682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru public void testLargeStringList() throws Exception { 1262682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru final int thresholdBytes = 256 * 1024; 1272682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru final String value = Long.toString(Long.MAX_VALUE); 1282682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru final int objectCount = 2 * thresholdBytes / value.length(); 1292682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru final List<String> list = Collections.nCopies(objectCount, value); 1302682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 1312682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru sendParcelStringList(list); 1322682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru } 1332682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 1342682fa70678ec79131329a6071d70c3d84c23d41Alexandru-Andrei Rotaru 135f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski /** 136f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * Test that only homogeneous elements may be unparceled. 137f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski */ 138f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public void testHomogeneousElements() throws Exception { 13948c95c4370533bf27e537cbca1e64d060a016c5fJon Larimer List<BaseObject> list = new ArrayList<BaseObject>(); 140f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski list.add(new LargeObject(0, 1, 2, 3, 4)); 141f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski list.add(new SmallObject(5, 6)); 142f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski list.add(new SmallObject(7, 8)); 143f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 144f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski Parcel parcel = Parcel.obtain(); 145f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski try { 146f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski writeEvilParceledListSlice(parcel, list); 147f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski parcel.setDataPosition(0); 148f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski try { 149f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski ParceledListSlice.CREATOR.createFromParcel(parcel, getClass().getClassLoader()); 150f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski assertTrue("Unparceled heterogeneous ParceledListSlice", false); 151f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } catch (IllegalArgumentException e) { 152f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // Success, we're not allowed to process heterogeneous 153f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // elements in a ParceledListSlice. 154f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 155f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } finally { 156f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski parcel.recycle(); 157f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 158f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 159f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 160f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski /** 161f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * Write a ParcelableListSlice that uses the BaseObject base class as the Creator. 162f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * This is dangerous, as it may affect how the data is unparceled, then later parceled 163f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * by the system, leading to a self-modifying data security vulnerability. 164f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski */ 165f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski private static <T extends BaseObject> void writeEvilParceledListSlice(Parcel dest, List<T> list) { 166f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski final int listCount = list.size(); 167f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 168f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // Number of items. 169f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(listCount); 170f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 171f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // The type/creator to use when unparceling. Here we use the base class 172f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // to simulate an attack on ParceledListSlice. 173f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeString(BaseObject.class.getName()); 174f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 175f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski for (int i = 0; i < listCount; i++) { 176f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // 1 means the item is present. 177f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(1); 178f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski list.get(i).writeToParcel(dest, 0); 179f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 180f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 181f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 182f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public abstract static class BaseObject implements Parcelable { 183f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski protected static final int TYPE_SMALL = 0; 184f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski protected static final int TYPE_LARGE = 1; 185f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 186f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski protected void writeToParcel(Parcel dest, int flags, int type) { 187f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(type); 188f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 189f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 190f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 191f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int describeContents() { 192f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return 0; 193f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 194f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 195f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski /** 196f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * This is *REALLY* bad, but we're doing it in the test to ensure that we handle 197f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * the possible exploit when unparceling an object with the BaseObject written as 198f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski * Creator. 199f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski */ 200f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static final Creator<BaseObject> CREATOR = new Creator<BaseObject>() { 201f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 202f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public BaseObject createFromParcel(Parcel source) { 203f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski switch (source.readInt()) { 204f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski case TYPE_SMALL: 205f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return SmallObject.createFromParcelBody(source); 206f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski case TYPE_LARGE: 207f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return LargeObject.createFromParcelBody(source); 208f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski default: 209f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski throw new IllegalArgumentException("Unknown type"); 210f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 211f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 212f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 213f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 214f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public BaseObject[] newArray(int size) { 215f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return new BaseObject[size]; 216f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 217f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski }; 218f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 219f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 220f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static class SmallObject extends BaseObject { 221f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldA; 222f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldB; 223f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 224f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public SmallObject(int a, int b) { 225f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldA = a; 226f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldB = b; 227f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 228f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 229f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 230f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public void writeToParcel(Parcel dest, int flags) { 231f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski super.writeToParcel(dest, flags, TYPE_SMALL); 232f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldA); 233f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldB); 234f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 235f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 236f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static SmallObject createFromParcelBody(Parcel source) { 237f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return new SmallObject(source.readInt(), source.readInt()); 238f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 239f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 240f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static final Creator<SmallObject> CREATOR = new Creator<SmallObject>() { 241f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 242f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public SmallObject createFromParcel(Parcel source) { 243f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // Consume the type (as it is always written out). 244f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt(); 245f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return createFromParcelBody(source); 246f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 247f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 248f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 249f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public SmallObject[] newArray(int size) { 250f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return new SmallObject[size]; 251f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 252f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski }; 253f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 254f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 255f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static class LargeObject extends BaseObject { 256f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldA; 257f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldB; 258f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldC; 259f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldD; 260f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public int mFieldE; 261f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 262f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public LargeObject(int a, int b, int c, int d, int e) { 263f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldA = a; 264f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldB = b; 265f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldC = c; 266f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldD = d; 267f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski mFieldE = e; 268f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 269f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 270f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 271f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public void writeToParcel(Parcel dest, int flags) { 272f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski super.writeToParcel(dest, flags, TYPE_LARGE); 273f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldA); 274f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldB); 275f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldC); 276f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldD); 277f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski dest.writeInt(mFieldE); 278f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 279f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 280f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static LargeObject createFromParcelBody(Parcel source) { 281f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return new LargeObject( 282f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt(), 283f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt(), 284f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt(), 285f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt(), 286f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt() 287f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski ); 288f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 289f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 290f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public static final Creator<LargeObject> CREATOR = new Creator<LargeObject>() { 291f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 292f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public LargeObject createFromParcel(Parcel source) { 293f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski // Consume the type (as it is always written out). 294f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski source.readInt(); 295f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return createFromParcelBody(source); 296f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 297f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski 298f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski @Override 299f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski public LargeObject[] newArray(int size) { 300f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski return new LargeObject[size]; 301f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 302f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski }; 303f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski } 304f741c3727383008b131cd3877cbdb3857e07fc9bAdam Lesinski} 305