Tag.java revision 2dcae567ab56285bc70b6857c4f3c87df09641b8
192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling/*
292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * Copyright (C) 2010 The Android Open Source Project
392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *
492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * Licensed under the Apache License, Version 2.0 (the "License");
592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * you may not use this file except in compliance with the License.
692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * You may obtain a copy of the License at
792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *
892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *      http://www.apache.org/licenses/LICENSE-2.0
992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *
1092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * Unless required by applicable law or agreed to in writing, software
1192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * distributed under the License is distributed on an "AS IS" BASIS,
1292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * See the License for the specific language governing permissions and
1492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * limitations under the License.
1592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling */
1692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
1792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingpackage android.nfc;
1892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
1992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.content.Context;
2092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.IsoDep;
2192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.MifareClassic;
2292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.MifareUltralight;
2392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.Ndef;
2492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.NdefFormatable;
2592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.NfcA;
2692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.NfcB;
2792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.NfcF;
2892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.NfcV;
2992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.nfc.tech.TagTechnology;
3092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.os.Bundle;
3192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.os.Parcel;
3292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.os.Parcelable;
3392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport android.os.RemoteException;
3492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
3592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport java.io.IOException;
3692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingimport java.util.Arrays;
3792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
3892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling/**
3992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * Represents an NFC tag that has been discovered.
4092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <p>
4192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link Tag} is an immutable object that represents the state of a NFC tag at
4292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * the time of discovery. It can be used as a handle to {@link TagTechnology} classes
4392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * to perform advanced operations, or directly queried for its ID via {@link #getId} and the
4492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * set of technologies it contains via {@link #getTechList}. Arrays passed to and
4592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * returned by this class are <em>not</em> cloned, so be careful not to modify them.
4692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <p>
4792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * A new tag object is created every time a tag is discovered (comes into range), even
4892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * if it is the same physical tag. If a tag is removed and then returned into range, then
4992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * only the most recent tag object can be successfully used to create a {@link TagTechnology}.
5092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *
5192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <h3>Tag Dispatch</h3>
5292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * When a tag is discovered, a {@link Tag} object is created and passed to a
534071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an
5492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used
5592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * to select the
5692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * most appropriate activity to handle the tag. The Android OS executes each stage in order,
5792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * and completes dispatch as soon as a single matching activity is found. If there are multiple
5892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * matching activities found at any one stage then the Android activity chooser dialog is shown
5992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * to allow the user to select the activity to receive the tag.
6092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *
6192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching
6292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * a tag to the correct activity without showing the user an activity chooser dialog.
6392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * This is important for NFC interactions because they are very transient -- if a user has to
6492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * move the Android device to choose an application then the connection will likely be broken.
6592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling *
6692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <h4>1. Foreground activity dispatch</h4>
6792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * A foreground activity that has called
6892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is
6992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * given priority. See the documentation on
7092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for
7192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * its usage.
7292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <h4>2. NDEF data dispatch</h4>
737738efc2f677583f9b6cd4404154b61ae9baddbdDima Zavin * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first
7492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data
757738efc2f677583f9b6cd4404154b61ae9baddbdDima Zavin * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI
7692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME
777738efc2f677583f9b6cd4404154b61ae9baddbdDima Zavin * type is put in the intent's type field. This allows activities to register to be launched only
7892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * when data they know how to handle is present on a tag. This is the preferred method of handling
79f2be60f5864338ca33d569f0086dac301b7066afDevin Kim * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a
80f2be60f5864338ca33d569f0086dac301b7066afDevin Kim * specific tag technology.
814071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain
8292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * NDEF data, or if no activity is registered
8392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch
8492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * moves to stage 3.
8592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <h4>3. Tag Technology dispatch</h4>
8692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to
8792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * dispatch the tag to an activity that can handle the technologies present on the tag.
8892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * Technologies are defined as sub-classes of {@link TagTechnology}, see the package
8992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or
903d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail.
9192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <h4>4. Fall-back dispatch</h4>
9292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * If no activity has been matched then {@link Context#startActivity} is called with
9392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism.
944071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}.
954071280488d3a261c39278b404aacc8701daef3eBongkyu Kim *
964071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * <h3>NFC Tag Background</h3>
974071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while
984071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or
994071280488d3a261c39278b404aacc8701daef3eBongkyu Kim * even embedded in a more sophisticated device.
10092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * <p>
10192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics,
10292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * and contain some one time
10392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * programmable areas to make read-only. More complex tags offer math operations
10492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * and per-sector access control and authentication. The most sophisticated tags
10592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * contain operating environments allowing complex interactions with the
10692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * code executing on the tag. Use {@link TagTechnology} classes to access a broad
10792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling * range of capabilities available in NFC tags.
1087738efc2f677583f9b6cd4404154b61ae9baddbdDima Zavin * <p>
10992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling */
11092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gillingpublic final class Tag implements Parcelable {
11192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ final byte[] mId;
11292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ final int[] mTechList;
11392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ final String[] mTechStringList;
11492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ final Bundle[] mTechExtras;
11592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
11692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ final INfcTag mTagService;
11792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
11892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ int mConnectedTechnology;
11992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
12092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
12192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * Hidden constructor to be used by NFC service and internal classes.
12292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @hide
12392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
12492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle,
12592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            INfcTag tagService) {
12692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (techList == null) {
12792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            throw new IllegalArgumentException("rawTargets cannot be null");
12892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
1295fb1aea7caade679d59ba57745660571ca191bb8Iliyan Malchev        mId = id;
13092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        mTechList = Arrays.copyOf(techList, techList.length);
13192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        mTechStringList = generateTechStringList(techList);
13292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        // Ensure mTechExtras is as long as mTechList
13392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        mTechExtras = Arrays.copyOf(techListExtras, techList.length);
13492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        mServiceHandle = serviceHandle;
13592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        mTagService = tagService;
13692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
13792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        mConnectedTechnology = -1;
13892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
13992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
14092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
14192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * Construct a mock Tag.
14292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail
14392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * with {@link IllegalArgumentException} since it does not represent a physical Tag.
14492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>This constructor might be useful for mock testing.
14592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @param id The tag identifier, can be null
14692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @param techList must not be null
14792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @return freshly constructed tag
14892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @hide
14992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
15092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) {
1515fb1aea7caade679d59ba57745660571ca191bb8Iliyan Malchev        // set serviceHandle to 0 to indicate mock tag
15292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return new Tag(id, techList, techListExtras, 0, null);
15392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
15492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
15592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    private String[] generateTechStringList(int[] techList) {
15692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        final int size = techList.length;
15792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        String[] strings = new String[size];
15892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        for (int i = 0; i < size; i++) {
15992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            switch (techList[i]) {
16092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.ISO_DEP:
16192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = IsoDep.class.getName();
16292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
16392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.MIFARE_CLASSIC:
16492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = MifareClassic.class.getName();
16592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
16692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.MIFARE_ULTRALIGHT:
16792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = MifareUltralight.class.getName();
16892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
16992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.NDEF:
17092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = Ndef.class.getName();
17192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
17292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.NDEF_FORMATABLE:
17392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = NdefFormatable.class.getName();
17492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
17592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.NFC_A:
17692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = NfcA.class.getName();
17792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
17892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.NFC_B:
17992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = NfcB.class.getName();
18092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
18192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.NFC_F:
18292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    strings[i] = NfcF.class.getName();
18392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    break;
18492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                case TagTechnology.NFC_V:
185f2be60f5864338ca33d569f0086dac301b7066afDevin Kim                    strings[i] = NfcV.class.getName();
186f2be60f5864338ca33d569f0086dac301b7066afDevin Kim                    break;
18792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                default:
18892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                    throw new IllegalArgumentException("Unknown tech type " + techList[i]);
18992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            }
19092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
19192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return strings;
19292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
19392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
19492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
19592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * For use by NfcService only.
19692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @hide
19792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
19892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public int getServiceHandle() {
19992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return mServiceHandle;
20092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
20192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
20292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
20392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * Get the Tag Identifier (if it has one).
20492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>The tag identifier is a low level serial number, used for anti-collision
20592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * and identification.
20692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p> Most tags have a stable unique identifier
20792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * (UID), but some tags will generate a random ID every time they are discovered
20892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * (RID), and there are some tags with no ID at all (the byte array will be zero-sized).
20992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p> The size and format of an ID is specific to the RF technology used by the tag.
21092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p> This function retrieves the ID as determined at discovery time, and does not
21192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * perform any further RF communication or block.
21292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @return ID as byte array, never null
21392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
21492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public byte[] getId() {
21592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return mId;
21692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
21792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
21892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
21992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * Get the technologies available in this tag, as fully qualified class names.
22092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>
22192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * A technology is an implementation of the {@link TagTechnology} interface,
22292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * and can be instantiated by calling the static <code>get(Tag)</code>
22392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * method on the implementation with this Tag. The {@link TagTechnology}
22492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * object can then be used to perform advanced, technology-specific operations on a tag.
22592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>
22692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * Android defines a mandatory set of technologies that must be correctly
22792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * enumerated by all Android NFC devices, and an optional
22892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * set of proprietary technologies.
22992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * See {@link TagTechnology} for more details.
23092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>
23192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * The ordering of the returned array is undefined and should not be relied upon.
23292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @return an array of fully-qualified {@link TagTechnology} class-names.
23392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
23492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public String[] getTechList() {
23592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return mTechStringList;
23692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
23792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
23892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
23992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * Rediscover the technologies available on this tag.
24092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>
24192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * The technologies that are available on a tag may change due to
24292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * operations being performed on a tag. For example, formatting a
24392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * tag as NDEF adds the {@link Ndef} technology. The {@link rediscover}
24492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * method reenumerates the available technologies on the tag
24592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * and returns a new {@link Tag} object containing these technologies.
24692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>
24792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * You may not be connected to any of this {@link Tag}'s technologies
24892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * when calling this method.
24992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * This method guarantees that you will be returned the same Tag
25092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * if it is still in the field.
25192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>May cause RF activity and may block. Must not be called
25292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * from the main application thread. A blocked call will be canceled with
25392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * {@link IOException} by calling {@link #close} from another thread.
25492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * <p>Does not remove power from the RF field, so a tag having a random
25592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * ID should not change its ID.
25692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @return the rediscovered tag object.
25792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @throws IOException if the tag cannot be rediscovered
25892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @hide
25992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
26092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    // TODO See if we need TagLostException
26192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    // TODO Unhide for ICS
26292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    // TODO Update documentation to make sure it matches with the final
26392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    //      implementation.
26492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public Tag rediscover() throws IOException {
26592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (getConnectedTechnology() != -1) {
26692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            throw new IllegalStateException("Close connection to the technology first!");
26792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
26892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
26992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        try {
27092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            Tag newTag = mTagService.rediscover(getServiceHandle());
27192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            if (newTag != null) {
27292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                return newTag;
27392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            } else {
27492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                throw new IOException("Failed to rediscover tag");
27592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            }
27692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        } catch (RemoteException e) {
27792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            throw new IOException("NFC service dead");
27892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
27992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
28092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
28192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
28292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /** @hide */
28392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public boolean hasTech(int techType) {
28492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        for (int tech : mTechList) {
28592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            if (tech == techType) return true;
28692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
28792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return false;
28892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
28992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
29092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /** @hide */
29192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public Bundle getTechExtras(int tech) {
29292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        int pos = -1;
29392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        for (int idx = 0; idx < mTechList.length; idx++) {
29492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling          if (mTechList[idx] == tech) {
29592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling              pos = idx;
29692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling              break;
29792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling          }
29892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
29992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (pos < 0) {
30092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            return null;
30192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
30292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
30392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return mTechExtras[pos];
30492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
305f2be60f5864338ca33d569f0086dac301b7066afDevin Kim
306f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    /** @hide */
307f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    public INfcTag getTagService() {
308f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        return mTagService;
30992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
310f2be60f5864338ca33d569f0086dac301b7066afDevin Kim
311f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    /**
312f2be60f5864338ca33d569f0086dac301b7066afDevin Kim     * Human-readable description of the tag, for debugging.
313f2be60f5864338ca33d569f0086dac301b7066afDevin Kim     */
314f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    @Override
31592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public String toString() {
316f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        StringBuilder sb = new StringBuilder("TAG ")
317f2be60f5864338ca33d569f0086dac301b7066afDevin Kim            .append("uid = ")
31892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            .append(mId)
31992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            .append(" Tech [");
32092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        for (int i : mTechList) {
32192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            sb.append(i)
32292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            .append(", ");
32392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
32492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return sb.toString();
32592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
32692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
32792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ static byte[] readBytesWithNull(Parcel in) {
32892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        int len = in.readInt();
32992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        byte[] result = null;
33092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (len >= 0) {
33192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            result = new byte[len];
33292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            in.readByteArray(result);
33392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
33492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        return result;
33592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
33692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
33792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) {
33892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (b == null) {
33992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            out.writeInt(-1);
34092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            return;
34192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
34292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        out.writeInt(b.length);
34392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        out.writeByteArray(b);
34492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
34592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
34692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    @Override
347f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    public int describeContents() {
348f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        return 0;
34992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
35092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
35192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    @Override
35292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public void writeToParcel(Parcel dest, int flags) {
35392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        // Null mTagService means this is a mock tag
35492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        int isMock = (mTagService == null)?1:0;
35592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
35692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        writeBytesWithNull(dest, mId);
35792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        dest.writeInt(mTechList.length);
35892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        dest.writeIntArray(mTechList);
35992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        dest.writeTypedArray(mTechExtras, 0);
36092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        dest.writeInt(mServiceHandle);
36192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        dest.writeInt(isMock);
36292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (isMock == 0) {
36392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            dest.writeStrongBinder(mTagService.asBinder());
36492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        }
36592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    }
36692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
36792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public static final Parcelable.Creator<Tag> CREATOR =
36892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            new Parcelable.Creator<Tag>() {
36992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        @Override
37092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        public Tag createFromParcel(Parcel in) {
37192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            INfcTag tagService;
37292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
37392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            // Tag fields
37492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            byte[] id = Tag.readBytesWithNull(in);
37592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            int[] techList = new int[in.readInt()];
37692e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            in.readIntArray(techList);
37792e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
37892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            int serviceHandle = in.readInt();
37992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            int isMock = in.readInt();
38092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            if (isMock == 0) {
38192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling                tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
38292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            }
38392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            else {
384f2be60f5864338ca33d569f0086dac301b7066afDevin Kim                tagService = null;
385f2be60f5864338ca33d569f0086dac301b7066afDevin Kim            }
386f2be60f5864338ca33d569f0086dac301b7066afDevin Kim
387f2be60f5864338ca33d569f0086dac301b7066afDevin Kim            return new Tag(id, techList, techExtras, serviceHandle, tagService);
388f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        }
389f2be60f5864338ca33d569f0086dac301b7066afDevin Kim
390f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        @Override
391f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        public Tag[] newArray(int size) {
392f2be60f5864338ca33d569f0086dac301b7066afDevin Kim            return new Tag[size];
393f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        }
394f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    };
395f2be60f5864338ca33d569f0086dac301b7066afDevin Kim
396f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    /**
397f2be60f5864338ca33d569f0086dac301b7066afDevin Kim     * For internal use only.
398f2be60f5864338ca33d569f0086dac301b7066afDevin Kim     *
39992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     * @hide
40092e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling     */
40192e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    public synchronized void setConnectedTechnology(int technology) {
40292e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        if (mConnectedTechnology == -1) {
40392e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            mConnectedTechnology = technology;
40492e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling        } else {
40592e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling            throw new IllegalStateException("Close other technology first!");
406f2be60f5864338ca33d569f0086dac301b7066afDevin Kim        }
407f2be60f5864338ca33d569f0086dac301b7066afDevin Kim    }
40892e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling
40992e19fda794d2d9b3a8dcf2301f29b2af4da4b8aErik Gilling    /**
4103d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     * For internal use only.
4113d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     *
4123d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     * @hide
4133d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     */
4143d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed    public int getConnectedTechnology() {
4153d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed        return mConnectedTechnology;
4163d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed    }
4173d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed
4183d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed    /**
4193d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     * For internal use only.
4203d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     *
4213d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     * @hide
4223d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed     */
4233d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed    public void setTechnologyDisconnected() {
4243d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed        mConnectedTechnology = -1;
4253d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed    }
4263d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed}
4273d163e306eece14820da529b2d9e98f8d6b269eaNaseer Ahmed