17e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornpackage android.os;
27e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
39630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport com.android.internal.util.ArrayUtils;
49630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
59630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brownimport java.util.Arrays;
69630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
77e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn/**
87e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn * Describes the source of some work that may be done by someone else.
97e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn * Currently the public representation of what a work source is is not
107e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn * defined; this is an opaque container.
117e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn */
127e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornpublic class WorkSource implements Parcelable {
137e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    int mNum;
147e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    int[] mUids;
157e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
167e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
177e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Internal statics to avoid object allocations in some operations.
187e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * The WorkSource object itself is not thread safe, but we need to
197e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * hold sTmpWorkSource lock while working with these statics.
207e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
217e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    static final WorkSource sTmpWorkSource = new WorkSource(0);
227e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
237e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * For returning newbie work from a modification operation.
247e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
257e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    static WorkSource sNewbWork;
267e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
277e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * For returning gone work form a modification operation.
287e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
297e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    static WorkSource sGoneWork;
307e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
317e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
327e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Create an empty work source.
337e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
347e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public WorkSource() {
357e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = 0;
367e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
377e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
387e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
397e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Create a new WorkSource that is a copy of an existing one.
407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * If <var>orig</var> is null, an empty WorkSource is created.
417e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
427e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public WorkSource(WorkSource orig) {
437e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (orig == null) {
447e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mNum = 0;
457e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return;
467e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = orig.mNum;
487e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (orig.mUids != null) {
497e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mUids = orig.mUids.clone();
507e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        } else {
517e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mUids = null;
527e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
537e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
547e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
557e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
567e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public WorkSource(int uid) {
577e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = 1;
587e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mUids = new int[] { uid, 0 };
597e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
607e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
617e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    WorkSource(Parcel in) {
627e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = in.readInt();
637e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mUids = in.createIntArray();
647e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
657e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
667e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
677e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public int size() {
687e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        return mNum;
697e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
707e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
717e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
727e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public int get(int index) {
737e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        return mUids[index];
747e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
757e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
767e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
777e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Clear this WorkSource to be empty.
787e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
797e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public void clear() {
807e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = 0;
817e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
827e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
8394838913abf6363532cd32b9c795917d808228ccJeff Brown    @Override
8494838913abf6363532cd32b9c795917d808228ccJeff Brown    public boolean equals(Object o) {
8594838913abf6363532cd32b9c795917d808228ccJeff Brown        return o instanceof WorkSource && !diff((WorkSource)o);
8694838913abf6363532cd32b9c795917d808228ccJeff Brown    }
8794838913abf6363532cd32b9c795917d808228ccJeff Brown
8894838913abf6363532cd32b9c795917d808228ccJeff Brown    @Override
8994838913abf6363532cd32b9c795917d808228ccJeff Brown    public int hashCode() {
9094838913abf6363532cd32b9c795917d808228ccJeff Brown        int result = 0;
9194838913abf6363532cd32b9c795917d808228ccJeff Brown        for (int i = 0; i < mNum; i++) {
9294838913abf6363532cd32b9c795917d808228ccJeff Brown            result = ((result << 4) | (result >>> 28)) ^ mUids[i];
9394838913abf6363532cd32b9c795917d808228ccJeff Brown        }
9494838913abf6363532cd32b9c795917d808228ccJeff Brown        return result;
9594838913abf6363532cd32b9c795917d808228ccJeff Brown    }
9694838913abf6363532cd32b9c795917d808228ccJeff Brown
977e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
987e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Compare this WorkSource with another.
997e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * @param other The WorkSource to compare against.
1007e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * @return If there is a difference, true is returned.
1017e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
1027e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public boolean diff(WorkSource other) {
1037e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        int N = mNum;
1047e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (N != other.mNum) {
1057e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return true;
1067e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1077e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int[] uids1 = mUids;
1087e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int[] uids2 = other.mUids;
1097e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        for (int i=0; i<N; i++) {
1107e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            if (uids1[i] != uids2[i]) {
1117e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                return true;
1127e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            }
1137e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1147e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        return false;
1157e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1167e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1177e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
1187e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Replace the current contents of this work source with the given
1197e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * work source.  If <var>other</var> is null, the current work source
1207e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * will be made empty.
1217e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
1227e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public void set(WorkSource other) {
1237e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (other == null) {
1247e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mNum = 0;
1257e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return;
1267e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1277e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = other.mNum;
1287e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (other.mUids != null) {
1297e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            if (mUids != null && mUids.length >= mNum) {
1307e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                System.arraycopy(other.mUids, 0, mUids, 0, mNum);
1317e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            } else {
1327e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                mUids = other.mUids.clone();
1337e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            }
1347e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        } else {
1357e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mUids = null;
1367e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1377e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1387e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1397e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
1407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public void set(int uid) {
1417e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = 1;
1427e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (mUids == null) mUids = new int[2];
1437e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mUids[0] = uid;
1447e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1457e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1467e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
1477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public WorkSource[] setReturningDiffs(WorkSource other) {
1487e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        synchronized (sTmpWorkSource) {
1497e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            sNewbWork = null;
1507e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            sGoneWork = null;
1517e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            updateLocked(other, true, true);
1527e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            if (sNewbWork != null || sGoneWork != null) {
1537e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                WorkSource[] diffs = new WorkSource[2];
1547e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                diffs[0] = sNewbWork;
1557e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                diffs[1] = sGoneWork;
1567e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                return diffs;
1577e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            }
1587e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return null;
1597e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1607e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1617e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1627e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /**
1637e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * Merge the contents of <var>other</var> WorkSource in to this one.
1647e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     *
1657e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * @param other The other WorkSource whose contents are to be merged.
1667e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     * @return Returns true if any new sources were added.
1677e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn     */
1687e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public boolean add(WorkSource other) {
1697e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        synchronized (sTmpWorkSource) {
1707e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return updateLocked(other, false, false);
1717e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1727e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1737e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1747e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
1757e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public WorkSource addReturningNewbs(WorkSource other) {
1767e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        synchronized (sTmpWorkSource) {
1777e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            sNewbWork = null;
1787e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            updateLocked(other, false, true);
1797e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return sNewbWork;
1807e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1817e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1827e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1837e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
1847e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public boolean add(int uid) {
1857e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        synchronized (sTmpWorkSource) {
1867e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            sTmpWorkSource.mUids[0] = uid;
1877e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return updateLocked(sTmpWorkSource, false, false);
1887e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1897e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
1907e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
1917e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    /** @hide */
1927e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public WorkSource addReturningNewbs(int uid) {
1937e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        synchronized (sTmpWorkSource) {
1947e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            sNewbWork = null;
1957e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            sTmpWorkSource.mUids[0] = uid;
1967e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            updateLocked(sTmpWorkSource, false, true);
1977e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return sNewbWork;
1987e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
1997e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
2007e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2017e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public boolean remove(WorkSource other) {
2027e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        int N1 = mNum;
2037e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int[] uids1 = mUids;
2047e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int N2 = other.mNum;
2057e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int[] uids2 = other.mUids;
2067e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        boolean changed = false;
2077e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        int i1 = 0;
2087e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        for (int i2=0; i2<N2 && i1<N1; i2++) {
2097e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            if (uids2[i2] == uids1[i1]) {
2107e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                N1--;
21183770289f8eca5aa4c62647a6c4d9a5bd4c80a45Dianne Hackborn                if (i1 < N1) System.arraycopy(uids1, i1+1, uids1, i1, N1-i1);
2127e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            }
2137e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            while (i1 < N1 && uids2[i2] > uids1[i1]) {
2147e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                i1++;
2157e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            }
2167e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
2177e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2187e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = N1;
2197e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2207e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        return changed;
2217e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
2227e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2237e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    private boolean updateLocked(WorkSource other, boolean set, boolean returnNewbs) {
2247e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        int N1 = mNum;
2257e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        int[] uids1 = mUids;
2267e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int N2 = other.mNum;
2277e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        final int[] uids2 = other.mUids;
2287e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        boolean changed = false;
2297e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        int i1 = 0;
2307e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        for (int i2=0; i2<N2; i2++) {
2317e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            if (i1 >= N1 || uids2[i2] < uids1[i1]) {
2327e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                // Need to insert a new uid.
2337e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                changed = true;
2347e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                if (uids1 == null) {
2357e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    uids1 = new int[4];
2367e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    uids1[0] = uids2[i2];
2377e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                } else if (i1 >= uids1.length) {
2387e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    int[] newuids = new int[(uids1.length*3)/2];
2397e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    if (i1 > 0) System.arraycopy(uids1, 0, newuids, 0, i1);
2407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    if (i1 < N1) System.arraycopy(uids1, i1, newuids, i1+1, N1-i1);
2417e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    uids1 = newuids;
2427e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    uids1[i1] = uids2[i2];
2437e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                } else {
2447e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    if (i1 < N1) System.arraycopy(uids1, i1, uids1, i1+1, N1-i1);
2457e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    uids1[i1] = uids2[i2];
2467e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                }
2477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                if (returnNewbs) {
2487e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    if (sNewbWork == null) {
2497e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        sNewbWork = new WorkSource(uids2[i2]);
2507e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    } else {
2517e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        sNewbWork.addLocked(uids2[i2]);
2527e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    }
2537e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                }
2547e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                N1++;
2557e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                i1++;
2567e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            } else {
2577e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                if (!set) {
2587e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    // Skip uids that already exist or are not in 'other'.
2597e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    do {
2607e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        i1++;
2617e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    } while (i1 < N1 && uids2[i2] >= uids1[i1]);
2627e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                } else {
2637e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    // Remove any uids that don't exist in 'other'.
2647e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    int start = i1;
2657e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    while (i1 < N1 && uids2[i2] > uids1[i1]) {
2667e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        if (sGoneWork == null) {
2677e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                            sGoneWork = new WorkSource(uids1[i1]);
2687e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        } else {
2697e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                            sGoneWork.addLocked(uids1[i1]);
2707e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        }
2717e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        i1++;
2727e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    }
2737e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    if (start < i1) {
2747e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        System.arraycopy(uids1, i1, uids1, start, i1-start);
2757e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        N1 -= i1-start;
2767e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        i1 = start;
2777e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    }
2787e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    // If there is a matching uid, skip it.
2797e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    if (i1 < N1 && uids2[i1] == uids1[i1]) {
2807e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                        i1++;
2817e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                    }
2827e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn                }
2837e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            }
2847e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
2857e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2867e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum = N1;
2877e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mUids = uids1;
2887e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2897e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        return changed;
2907e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
2917e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
2927e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    private void addLocked(int uid) {
2937e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (mUids == null) {
2947e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mUids = new int[4];
2957e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mUids[0] = uid;
2967e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mNum = 1;
2977e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return;
2987e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
2997e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        if (mNum >= mUids.length) {
3007e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            int[] newuids = new int[(mNum*3)/2];
3017e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            System.arraycopy(mUids, 0, newuids, 0, mNum);
3027e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            mUids = newuids;
3037e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
3047e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
3057e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mUids[mNum] = uid;
3067e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        mNum++;
3077e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
3087e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
3097e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    @Override
3107e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public int describeContents() {
3117e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        return 0;
3127e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
3137e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
3147e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    @Override
3157e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public void writeToParcel(Parcel dest, int flags) {
3167e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        dest.writeInt(mNum);
3177e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        dest.writeIntArray(mUids);
3187e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    }
3197e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn
3209630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    @Override
3219630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    public String toString() {
3229630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        StringBuilder result = new StringBuilder();
3239630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        result.append("{WorkSource: uids=[");
3249630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        for (int i = 0; i < mNum; i++) {
3259630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            if (i != 0) {
3269630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown                result.append(", ");
3279630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            }
3289630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown            result.append(mUids[i]);
3299630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        }
3309630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        result.append("]}");
3319630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown        return result.toString();
3329630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown    }
3339630704ed3b265f008a8f64ec60a33cf9dcd3345Jeff Brown
3347e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    public static final Parcelable.Creator<WorkSource> CREATOR
3357e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            = new Parcelable.Creator<WorkSource>() {
3367e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        public WorkSource createFromParcel(Parcel in) {
3377e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return new WorkSource(in);
3387e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
3397e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        public WorkSource[] newArray(int size) {
3407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn            return new WorkSource[size];
3417e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn        }
3427e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn    };
3437e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn}
344