10e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root/*
20e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * Copyright (C) 2011 The Android Open Source Project
30e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root *
40e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
50e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * you may not use this file except in compliance with the License.
60e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * You may obtain a copy of the License at
70e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root *
80e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
90e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root *
100e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * Unless required by applicable law or agreed to in writing, software
110e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
120e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * See the License for the specific language governing permissions and
140e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * limitations under the License.
150e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root */
160e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
170e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Rootpackage android.content.pm;
180e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
19d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackbornimport android.os.Binder;
20d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackbornimport android.os.IBinder;
210e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Rootimport android.os.Parcel;
220e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Rootimport android.os.Parcelable;
23d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackbornimport android.os.RemoteException;
24d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackbornimport android.util.Log;
250e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
26d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackbornimport java.util.ArrayList;
272f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkeyimport java.util.Collections;
280e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Rootimport java.util.List;
290e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
300e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root/**
31d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn * Transfer a large list of Parcelable objects across an IPC.  Splits into
32d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn * multiple transactions if needed.
330e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root *
343df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski * Caveat: for efficiency and security, all elements must be the same concrete type.
353df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski * In order to avoid writing the class name of each object, we must ensure that
363df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski * each object is the same type, or else unparceling then reparceling the data may yield
373df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski * a different result if the class name encoded in the Parcelable is a Base type.
383df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski * See b/17671747.
393df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski *
400e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root * @hide
410e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root */
420e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Rootpublic class ParceledListSlice<T extends Parcelable> implements Parcelable {
43d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    private static String TAG = "ParceledListSlice";
44d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    private static boolean DEBUG = false;
45d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn
460e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    /*
470e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     * TODO get this number from somewhere else. For now set it to a quarter of
480e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     * the 1MB limit.
490e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     */
5086cbc2bf30a7623b2ad6564cf50ca20f87067ea7Dianne Hackborn    private static final int MAX_IPC_SIZE = IBinder.MAX_IPC_SIZE;
510e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
52d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    private final List<T> mList;
530e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
542f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey    public static <T extends Parcelable> ParceledListSlice<T> emptyList() {
552f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey        return new ParceledListSlice<T>(Collections.<T> emptyList());
562f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey    }
572f3e35376ada0327b34a71d7c45ac6e6d955d7dcJeff Sharkey
58d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    public ParceledListSlice(List<T> list) {
59d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        mList = list;
60d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    }
610e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
6244e440cc7e834de7811f005998acb32716835b00Neil Fuller    @SuppressWarnings("unchecked")
63d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    private ParceledListSlice(Parcel p, ClassLoader loader) {
64d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        final int N = p.readInt();
65d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        mList = new ArrayList<T>(N);
66d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        if (DEBUG) Log.d(TAG, "Retrieving " + N + " items");
67d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        if (N <= 0) {
68d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            return;
69d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        }
703df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
7144e440cc7e834de7811f005998acb32716835b00Neil Fuller        Parcelable.Creator<?> creator = p.readParcelableCreator(loader);
723df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski        Class<?> listElementClass = null;
733df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
74d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        int i = 0;
75d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        while (i < N) {
76d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            if (p.readInt() == 0) {
77d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                break;
78d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            }
793df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
803df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            final T parcelable = p.readCreator(creator, loader);
813df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            if (listElementClass == null) {
823df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                listElementClass = parcelable.getClass();
833df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            } else {
843df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                verifySameType(listElementClass, parcelable.getClass());
853df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            }
863df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
873df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            mList.add(parcelable);
883df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
89d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1));
90d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            i++;
91d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        }
92d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        if (i >= N) {
93d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            return;
94d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        }
95d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        final IBinder retriever = p.readStrongBinder();
96d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        while (i < N) {
97d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever);
98d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            Parcel data = Parcel.obtain();
99d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            Parcel reply = Parcel.obtain();
100d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            data.writeInt(i);
101d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            try {
102d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
103d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            } catch (RemoteException e) {
104d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                Log.w(TAG, "Failure retrieving array; only received " + i + " of " + N, e);
105d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                return;
106d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            }
107d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            while (i < N && reply.readInt() != 0) {
1083df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                final T parcelable = reply.readCreator(creator, loader);
1093df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                verifySameType(listElementClass, parcelable.getClass());
1103df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
1113df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                mList.add(parcelable);
1123df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
113d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1));
114d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                i++;
115d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            }
116d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            reply.recycle();
117d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            data.recycle();
118d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        }
1190e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    }
1200e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
1213df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski    private static void verifySameType(final Class<?> expected, final Class<?> actual) {
1223df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski        if (!actual.equals(expected)) {
1233df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            throw new IllegalArgumentException("Can't unparcel type "
1243df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                    + actual.getName() + " in list of type "
1253df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                    + expected.getName());
1263df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski        }
1273df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski    }
1283df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
129d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    public List<T> getList() {
130d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        return mList;
1310e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    }
1320e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
1330e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    @Override
1340e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    public int describeContents() {
135d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        int contents = 0;
136d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        for (int i=0; i<mList.size(); i++) {
137d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            contents |= mList.get(i).describeContents();
138d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        }
139d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        return contents;
1400e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    }
1410e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
1420e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    /**
1430e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     * Write this to another Parcel. Note that this discards the internal Parcel
1440e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     * and should not be used anymore. This is so we can pass this to a Binder
1450e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     * where we won't have a chance to call recycle on this.
1460e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root     */
1470e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    @Override
1480e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    public void writeToParcel(Parcel dest, int flags) {
149d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        final int N = mList.size();
150d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        final int callFlags = flags;
151d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        dest.writeInt(N);
152d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        if (DEBUG) Log.d(TAG, "Writing " + N + " items");
153d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        if (N > 0) {
1543df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski            final Class<?> listElementClass = mList.get(0).getClass();
155d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            dest.writeParcelableCreator(mList.get(0));
156d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            int i = 0;
15786cbc2bf30a7623b2ad6564cf50ca20f87067ea7Dianne Hackborn            while (i < N && dest.dataSize() < MAX_IPC_SIZE) {
158d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                dest.writeInt(1);
1593df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
1603df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                final T parcelable = mList.get(i);
1613df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                verifySameType(listElementClass, parcelable.getClass());
1623df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                parcelable.writeToParcel(dest, callFlags);
1633df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
164d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
165d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                i++;
166d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            }
167d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            if (i < N) {
168d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                dest.writeInt(0);
169d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                Binder retriever = new Binder() {
170d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                    @Override
171d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
172d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            throws RemoteException {
173d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        if (code != FIRST_CALL_TRANSACTION) {
174d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            return super.onTransact(code, data, reply, flags);
175d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        }
176d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        int i = data.readInt();
177d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N);
178d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        while (i < N && reply.dataSize() < MAX_IPC_SIZE) {
179d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            reply.writeInt(1);
1803df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
1813df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                            final T parcelable = mList.get(i);
1823df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                            verifySameType(listElementClass, parcelable.getClass());
1833df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski                            parcelable.writeToParcel(reply, callFlags);
1843df1c38ee098872352086e03d6f1adb16796ee29Adam Lesinski
185d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
186d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            i++;
187d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        }
188d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        if (i < N) {
189d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N);
190d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                            reply.writeInt(0);
191d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        }
192d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                        return true;
193d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                    }
194d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                };
195d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N + ": retriever=" + retriever);
196d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn                dest.writeStrongBinder(retriever);
197d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            }
1980e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root        }
1990e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    }
2000e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
2010e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    @SuppressWarnings("unchecked")
202d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn    public static final Parcelable.ClassLoaderCreator<ParceledListSlice> CREATOR =
203d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            new Parcelable.ClassLoaderCreator<ParceledListSlice>() {
2040e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root        public ParceledListSlice createFromParcel(Parcel in) {
205d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            return new ParceledListSlice(in, null);
206d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        }
2070e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
208d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        @Override
209d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn        public ParceledListSlice createFromParcel(Parcel in, ClassLoader loader) {
210d8e1dbb6bc1fbaf4f2e38c3ba92ced94270deaacDianne Hackborn            return new ParceledListSlice(in, loader);
2110e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root        }
2120e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root
2130e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root        public ParceledListSlice[] newArray(int size) {
2140e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root            return new ParceledListSlice[size];
2150e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root        }
2160e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root    };
2170e2c0f37d98bb5539b0fe41865aaf1add0ff1bb3Kenny Root}
218