Tag.java revision 5289b91c885158094988a9a7b51b3139565eb639
1590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/*
2590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Copyright (C) 2010 The Android Open Source Project
3590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly *
4590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
5590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * you may not use this file except in compliance with the License.
6590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * You may obtain a copy of the License at
7590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly *
8590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
9590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly *
10590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Unless required by applicable law or agreed to in writing, software
11590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
12590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * See the License for the specific language governing permissions and
14590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * limitations under the License.
15590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */
16590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
17590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellypackage android.nfc;
18590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
196be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.IsoDep;
206be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.MifareClassic;
212fe24e3e14cce791e89c93ddc23e28af5c2c90ccJan Brandsimport android.nfc.technology.MifareUltralight;
226be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.NfcV;
236be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.Ndef;
245289b91c885158094988a9a7b51b3139565eb639Martijn Coenenimport android.nfc.technology.NdefFormatable;
256be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.NfcA;
266be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.NfcB;
276be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.NfcF;
286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.technology.TagTechnology;
296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.Bundle;
30590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.Parcel;
31590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.Parcelable;
326be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.RemoteException;
336be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton
346be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport java.util.Arrays;
35590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
36590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/**
37c9f7890a203a013646650a695157277df81b6a17Scott Main * Represents a (generic) discovered tag.
38590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p>
39590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags,
40590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Sony Felica Tags.
41590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p>
42590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * Tag's have a type and usually have a UID.
43590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p>
44c9f7890a203a013646650a695157277df81b6a17Scott Main * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra
45c9f7890a203a013646650a695157277df81b6a17Scott Main * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable
46c9f7890a203a013646650a695157277df81b6a17Scott Main * and represents the state of the tag at the time of discovery. It can be
476be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * directly queried for its UID and Type, or used to create a {@link TagTechnology}
486be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * (with {@link Tag#getTechnology(int)}).
49590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p>
506be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * A {@link Tag} can  be used to create a {@link TagTechnology} only while the tag is in
51c9f7890a203a013646650a695157277df81b6a17Scott Main * range. If it is removed and then returned to range, then the most recent
52c9f7890a203a013646650a695157277df81b6a17Scott Main * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a
536be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * {@link TagTechnology}.
5407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * <p>This is an immutable data class. All properties are set at Tag discovery
5507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * time and calls on this class will retrieve those read-only properties, and
5607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * not cause any further RF activity or block. Note however that arrays passed to and
5707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * returned by this class are *not* cloned, so be careful not to modify them.
5811b075e218b9921a953eeebe73fcd1a8a81f764bNick Pelly * @hide
59590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */
60590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellypublic class Tag implements Parcelable {
6107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    /*package*/ final byte[] mId;
626be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton    /*package*/ final int[] mTechList;
636be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton    /*package*/ final Bundle[] mTechExtras;
6407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    /*package*/ final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
65a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau
66590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    /**
6707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * Hidden constructor to be used by NFC service and internal classes.
68590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     * @hide
69590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     */
706be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton    public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle) {
716be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        if (techList == null) {
7207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            throw new IllegalArgumentException("rawTargets cannot be null");
7307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        }
7407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        mId = id;
756be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        mTechList = Arrays.copyOf(techList, techList.length);
766be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        // Ensure mTechExtras is as long as mTechList
776be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        mTechExtras = Arrays.copyOf(techListExtras, techList.length);
7807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        mServiceHandle = serviceHandle;
7907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    }
8007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly
8107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    /**
8207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * Construct a mock Tag.
8307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * <p>This is an application constructed tag, so NfcAdapter methods on this
846be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton     * Tag such as {@link #getTechnology} may fail with
8507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * {@link IllegalArgumentException} since it does not represent a physical Tag.
8607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * <p>This constructor might be useful for mock testing.
8707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * @param id The tag identifier, can be null
886be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton     * @param techList must not be null
8907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * @return freshly constructed tag
9007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     */
916be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) {
9207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        // set serviceHandle to 0 to indicate mock tag
936be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        return new Tag(id, techList, techListExtras, 0);
94590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    }
95590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
96590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    /**
97590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     * For use by NfcService only.
98590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     * @hide
99590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     */
10007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    public int getServiceHandle() {
10107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        return mServiceHandle;
102590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    }
103590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
104590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    /**
10507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * Get the Tag Identifier (if it has one).
10607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * <p>Tag ID is usually a serial number for the tag.
107590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     *
10807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     * @return ID, or null if it does not exist
10907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly     */
11007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    public byte[] getId() {
11107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        return mId;
11207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    }
11307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly
11407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    /**
1156be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton     * Returns technologies present in the tag that this implementation understands,
1166be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton     * or a zero length array if there are no supported technologies on this tag.
117c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton     *
118c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton     * The elements of the list are guaranteed be one of the constants defined in
119c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton     * {@link TagTechnology}.
120c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton     *
121c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton     * The ordering of the returned array is undefined and should not be relied upon.
122590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     */
1236be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton    public int[] getTechnologyList() {
1246be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        return Arrays.copyOf(mTechList, mTechList.length);
125590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    }
126590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
127590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    /**
1286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton     * Returns the technology, or null if not present
129590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly     */
1306be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton    public TagTechnology getTechnology(int tech) {
1311253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen        int pos = -1;
1321253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen        for (int idx = 0; idx < mTechList.length; idx++) {
1331253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen          if (mTechList[idx] == tech) {
1341253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen              pos = idx;
1351253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen              break;
1361253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen          }
1371253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen        }
1386be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        if (pos < 0) {
1396be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            return null;
1406be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        }
1416be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton
1426be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        Bundle extras = mTechExtras[pos];
1431253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen        NfcAdapter adapter = NfcAdapter.getDefaultAdapter();
1446be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        try {
1456be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            switch (tech) {
1466be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                case TagTechnology.NFC_A: {
1476be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new NfcA(adapter, this, extras);
1486be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1496be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                case TagTechnology.NFC_B: {
1506be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new NfcB(adapter, this, extras);
1516be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1526be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                case TagTechnology.ISO_DEP: {
1536be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new IsoDep(adapter, this, extras);
1546be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1556be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                case TagTechnology.NFC_V: {
1566be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new NfcV(adapter, this, extras);
1576be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
15872df4ea8300ad345eb256cf43d8dae35eef39ba2Martijn Coenen                case TagTechnology.NDEF: {
1596be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new Ndef(adapter, this, tech, extras);
1606be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1615289b91c885158094988a9a7b51b3139565eb639Martijn Coenen                case TagTechnology.NDEF_FORMATABLE: {
1625289b91c885158094988a9a7b51b3139565eb639Martijn Coenen                    return new NdefFormatable(adapter, this, tech, extras);
1635289b91c885158094988a9a7b51b3139565eb639Martijn Coenen                }
1646be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                case TagTechnology.NFC_F: {
1656be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new NfcF(adapter, this, extras);
1666be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1676be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                case TagTechnology.MIFARE_CLASSIC: {
1686be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    return new MifareClassic(adapter, this, extras);
1696be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1702fe24e3e14cce791e89c93ddc23e28af5c2c90ccJan Brands                case TagTechnology.MIFARE_ULTRALIGHT: {
1712fe24e3e14cce791e89c93ddc23e28af5c2c90ccJan Brands                    return new MifareUltralight(adapter, this, extras);
1722fe24e3e14cce791e89c93ddc23e28af5c2c90ccJan Brands                }
1736be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton
1746be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                default: {
1756be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                    throw new UnsupportedOperationException("Tech " + tech + " not supported");
1766be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton                }
1776be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            }
1786be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        } catch (RemoteException e) {
1796be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            return null;
1806be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        }
18107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    }
18207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly
18307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    @Override
18407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    public String toString() {
18507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        StringBuilder sb = new StringBuilder("TAG ")
18607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            .append("uid = ")
18707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            .append(mId)
1886be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            .append(" Tech [");
1896be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        for (int i : mTechList) {
1906be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            sb.append(i)
19107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            .append(", ");
19207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        }
19307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        return sb.toString();
19407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    }
19507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly
19607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    /*package*/ static byte[] readBytesWithNull(Parcel in) {
19707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        int len = in.readInt();
19807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        byte[] result = null;
199e2e4ea9ea8f5724403e6267d193a740dc7c78785Sylvain Fonteneau        if (len >= 0) {
20007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            result = new byte[len];
20107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            in.readByteArray(result);
202590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly        }
20307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        return result;
20407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    }
20507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly
20607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly    /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) {
20707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        if (b == null) {
20807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            out.writeInt(-1);
20907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            return;
21007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        }
21107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        out.writeInt(b.length);
21207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        out.writeByteArray(b);
213590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    }
214590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
215590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    @Override
216590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    public int describeContents() {
217590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly        return 0;
218590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    }
219590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
220590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    @Override
221590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    public void writeToParcel(Parcel dest, int flags) {
22207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        writeBytesWithNull(dest, mId);
2236be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        dest.writeInt(mTechList.length);
2246be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        dest.writeIntArray(mTechList);
2256be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        dest.writeTypedArray(mTechExtras, 0);
22607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly        dest.writeInt(mServiceHandle);
227590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    }
228590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly
229590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    public static final Parcelable.Creator<Tag> CREATOR =
230590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly            new Parcelable.Creator<Tag>() {
2316be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        @Override
232590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly        public Tag createFromParcel(Parcel in) {
23307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            // Tag fields
23407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            byte[] id = Tag.readBytesWithNull(in);
2356be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            int[] techList = new int[in.readInt()];
2366be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            in.readIntArray(techList);
2376be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
23807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly            int serviceHandle = in.readInt();
23907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly
2406be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton            return new Tag(id, techList, techExtras, serviceHandle);
241590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly        }
2426be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton
2436be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton        @Override
244590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly        public Tag[] newArray(int size) {
245590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly            return new Tag[size];
246590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly        }
247590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly    };
2481253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen}
249