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 1974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pellyimport android.content.Context; 20d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.IsoDep; 21d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.MifareClassic; 22d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.MifareUltralight; 23d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.Ndef; 24d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NdefFormatable; 25d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcA; 26d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcB; 27ca0cf4ee782e474961e6de74f6004781773f957cMartijn Coenenimport android.nfc.tech.NfcBarcode; 28d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcF; 29d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamiltonimport android.nfc.tech.NfcV; 304e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonimport android.nfc.tech.TagTechnology; 316be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.Bundle; 32590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.Parcel; 33590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pellyimport android.os.Parcelable; 342dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenenimport android.os.RemoteException; 356be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 362dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenenimport java.io.IOException; 376be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport java.util.Arrays; 38d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Moralesimport java.util.HashMap; 39590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 40590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly/** 4174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Represents an NFC tag that has been discovered. 42590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 4374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link Tag} is an immutable object that represents the state of a NFC tag at 4474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * the time of discovery. It can be used as a handle to {@link TagTechnology} classes 4528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to perform advanced operations, or directly queried for its ID via {@link #getId} and the 4628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * set of technologies it contains via {@link #getTechList}. Arrays passed to and 4728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * returned by this class are <em>not</em> cloned, so be careful not to modify them. 48590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 4974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * A new tag object is created every time a tag is discovered (comes into range), even 5074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * if it is the same physical tag. If a tag is removed and then returned into range, then 5174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * only the most recent tag object can be successfully used to create a {@link TagTechnology}. 5274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 5374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h3>Tag Dispatch</h3> 5474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * When a tag is discovered, a {@link Tag} object is created and passed to a 5528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an 5628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used 5728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to select the 5828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * most appropriate activity to handle the tag. The Android OS executes each stage in order, 5928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * and completes dispatch as soon as a single matching activity is found. If there are multiple 6028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * matching activities found at any one stage then the Android activity chooser dialog is shown 6128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * to allow the user to select the activity to receive the tag. 6228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 6328319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching 6428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * a tag to the correct activity without showing the user an activity chooser dialog. 6528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * This is important for NFC interactions because they are very transient -- if a user has to 6628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * move the Android device to choose an application then the connection will likely be broken. 6728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * 6874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>1. Foreground activity dispatch</h4> 6928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * A foreground activity that has called 7028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is 7128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * given priority. See the documentation on 7228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for 7374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * its usage. 7474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>2. NDEF data dispatch</h4> 7528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first 7628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data 7728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI 7828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME 7928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * type is put in the intent's type field. This allows activities to register to be launched only 8028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * when data they know how to handle is present on a tag. This is the preferred method of handling 8128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a 8228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * specific tag technology. 8374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain 8428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * NDEF data, or if no activity is registered 8528319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch 8628319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * moves to stage 3. 8774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>3. Tag Technology dispatch</h4> 8874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to 8928319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * dispatch the tag to an activity that can handle the technologies present on the tag. 9074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Technologies are defined as sub-classes of {@link TagTechnology}, see the package 9128319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or 9228319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail. 9374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h4>4. Fall-back dispatch</h4> 9428319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * If no activity has been matched then {@link Context#startActivity} is called with 9574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism. 9674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}. 9774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 9874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <h3>NFC Tag Background</h3> 9974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while 10028319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or 10174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * even embedded in a more sophisticated device. 10274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 10374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics, 10474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and contain some one time 10574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * programmable areas to make read-only. More complex tags offer math operations 10674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and per-sector access control and authentication. The most sophisticated tags 10728319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * contain operating environments allowing complex interactions with the 10828319c0cec94977682db32b949628a8e4b8183dcJeff Hamilton * code executing on the tag. Use {@link TagTechnology} classes to access a broad 10974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * range of capabilities available in NFC tags. 110590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * <p> 111590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 112f003e26df96067b4b136f0859012cb7ec3ed930fNick Pellypublic final class Tag implements Parcelable { 1131f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final byte[] mId; 1141f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final int[] mTechList; 1151f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final String[] mTechStringList; 1161f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final Bundle[] mTechExtras; 1171f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final int mServiceHandle; // for use by NFC service, 0 indicates a mock 1181f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly final INfcTag mTagService; // interface to NFC service, will be null if mock tag 119a926540d5455a973dd8ca19c00c108620d9c68c2Sylvain Fonteneau 1201f5badc1cb08f10ddf4b09aaaf34060a23999a51Nick Pelly int mConnectedTechnology; 1214049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 122590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 12307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * Hidden constructor to be used by NFC service and internal classes. 124590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 125590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 1264e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle, 1274e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton INfcTag tagService) { 1286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton if (techList == null) { 12907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly throw new IllegalArgumentException("rawTargets cannot be null"); 13007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 13107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly mId = id; 1326be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mTechList = Arrays.copyOf(techList, techList.length); 133d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton mTechStringList = generateTechStringList(techList); 1346be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton // Ensure mTechExtras is as long as mTechList 1356be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mTechExtras = Arrays.copyOf(techListExtras, techList.length); 13607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly mServiceHandle = serviceHandle; 1374e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton mTagService = tagService; 1384049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 1394049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen mConnectedTechnology = -1; 14007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 14107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 14207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /** 14307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * Construct a mock Tag. 1444e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail 1454e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * with {@link IllegalArgumentException} since it does not represent a physical Tag. 14607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * <p>This constructor might be useful for mock testing. 14707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * @param id The tag identifier, can be null 1486be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * @param techList must not be null 14907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * @return freshly constructed tag 150f003e26df96067b4b136f0859012cb7ec3ed930fNick Pelly * @hide 15107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly */ 1526be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) { 15323fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen // set serviceHandle to 0 and tagService to null to indicate mock tag 1544e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new Tag(id, techList, techListExtras, 0, null); 155590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 156590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 157d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton private String[] generateTechStringList(int[] techList) { 158d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton final int size = techList.length; 159d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton String[] strings = new String[size]; 160d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton for (int i = 0; i < size; i++) { 161d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton switch (techList[i]) { 162d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.ISO_DEP: 163d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = IsoDep.class.getName(); 164d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 165d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.MIFARE_CLASSIC: 166d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = MifareClassic.class.getName(); 167d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 168d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.MIFARE_ULTRALIGHT: 169d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = MifareUltralight.class.getName(); 170d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 171d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NDEF: 172d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = Ndef.class.getName(); 173d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 174d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NDEF_FORMATABLE: 175d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NdefFormatable.class.getName(); 176d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 177d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_A: 178d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcA.class.getName(); 179d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 180d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_B: 181d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcB.class.getName(); 182d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 183d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_F: 184d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcF.class.getName(); 185d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 186d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton case TagTechnology.NFC_V: 187d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton strings[i] = NfcV.class.getName(); 188d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton break; 189ca0cf4ee782e474961e6de74f6004781773f957cMartijn Coenen case TagTechnology.NFC_BARCODE: 190ca0cf4ee782e474961e6de74f6004781773f957cMartijn Coenen strings[i] = NfcBarcode.class.getName(); 191ca0cf4ee782e474961e6de74f6004781773f957cMartijn Coenen break; 192d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton default: 193d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton throw new IllegalArgumentException("Unknown tech type " + techList[i]); 194d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 195d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 196d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton return strings; 197d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton } 198d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton 19911d2e53dc0d2682f66f8dcbd8f0ad52432cb4aa7Andres Morales static int[] getTechCodesFromStrings(String[] techStringList) throws IllegalArgumentException { 200d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales if (techStringList == null) { 201d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales throw new IllegalArgumentException("List cannot be null"); 202d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales } 203d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales int[] techIntList = new int[techStringList.length]; 204d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales HashMap<String, Integer> stringToCodeMap = getTechStringToCodeMap(); 205d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales for (int i = 0; i < techStringList.length; i++) { 206d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales Integer code = stringToCodeMap.get(techStringList[i]); 207d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales 208d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales if (code == null) { 209d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales throw new IllegalArgumentException("Unknown tech type " + techStringList[i]); 210d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales } 211d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales 212d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techIntList[i] = code.intValue(); 213d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales } 214d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales return techIntList; 215d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales } 216d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales 217d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales private static HashMap<String, Integer> getTechStringToCodeMap() { 218d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales HashMap<String, Integer> techStringToCodeMap = new HashMap<String, Integer>(); 219d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales 220d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(IsoDep.class.getName(), TagTechnology.ISO_DEP); 221d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(MifareClassic.class.getName(), TagTechnology.MIFARE_CLASSIC); 222d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(MifareUltralight.class.getName(), TagTechnology.MIFARE_ULTRALIGHT); 223d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(Ndef.class.getName(), TagTechnology.NDEF); 224d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(NdefFormatable.class.getName(), TagTechnology.NDEF_FORMATABLE); 225d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(NfcA.class.getName(), TagTechnology.NFC_A); 226d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(NfcB.class.getName(), TagTechnology.NFC_B); 227d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(NfcF.class.getName(), TagTechnology.NFC_F); 228d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(NfcV.class.getName(), TagTechnology.NFC_V); 229d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales techStringToCodeMap.put(NfcBarcode.class.getName(), TagTechnology.NFC_BARCODE); 230d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales 231d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales return techStringToCodeMap; 232d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales } 233d8cf53f87d1416613aa34cfb28f5042033e3299cAndres Morales 234590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 235590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * For use by NfcService only. 236590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly * @hide 237590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 23807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly public int getServiceHandle() { 23907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return mServiceHandle; 240590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 241590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 242590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly /** 2433e4b665bc607c81ccc018d753122a363dd95159bAndres Morales * For use by NfcService only. 2443e4b665bc607c81ccc018d753122a363dd95159bAndres Morales * @hide 2453e4b665bc607c81ccc018d753122a363dd95159bAndres Morales */ 2463e4b665bc607c81ccc018d753122a363dd95159bAndres Morales public int[] getTechCodeList() { 2473e4b665bc607c81ccc018d753122a363dd95159bAndres Morales return mTechList; 2483e4b665bc607c81ccc018d753122a363dd95159bAndres Morales } 2493e4b665bc607c81ccc018d753122a363dd95159bAndres Morales 2503e4b665bc607c81ccc018d753122a363dd95159bAndres Morales /** 25107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly * Get the Tag Identifier (if it has one). 25274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>The tag identifier is a low level serial number, used for anti-collision 25374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and identification. 25474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> Most tags have a stable unique identifier 25574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * (UID), but some tags will generate a random ID every time they are discovered 25674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * (RID), and there are some tags with no ID at all (the byte array will be zero-sized). 25774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> The size and format of an ID is specific to the RF technology used by the tag. 25874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> This function retrieves the ID as determined at discovery time, and does not 25974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * perform any further RF communication or block. 26074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return ID as byte array, never null 26107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly */ 26207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly public byte[] getId() { 26307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return mId; 26407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 26507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 26607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /** 26774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get the technologies available in this tag, as fully qualified class names. 26874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 26974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * A technology is an implementation of the {@link TagTechnology} interface, 27074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * and can be instantiated by calling the static <code>get(Tag)</code> 27174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * method on the implementation with this Tag. The {@link TagTechnology} 27274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * object can then be used to perform advanced, technology-specific operations on a tag. 27374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 27474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Android defines a mandatory set of technologies that must be correctly 27574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * enumerated by all Android NFC devices, and an optional 27674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * set of proprietary technologies. 27774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * See {@link TagTechnology} for more details. 27874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p> 279c1576ad627d3d2b2d3c0764c605ebbf3ddc24401Jeff Hamilton * The ordering of the returned array is undefined and should not be relied upon. 28074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return an array of fully-qualified {@link TagTechnology} class-names. 281590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly */ 282d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton public String[] getTechList() { 283d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0Jeff Hamilton return mTechStringList; 284590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 285590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 2862dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen /** 2872dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * Rediscover the technologies available on this tag. 2882dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p> 2892dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * The technologies that are available on a tag may change due to 2902dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * operations being performed on a tag. For example, formatting a 2912dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * tag as NDEF adds the {@link Ndef} technology. The {@link rediscover} 2922dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * method reenumerates the available technologies on the tag 2932dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * and returns a new {@link Tag} object containing these technologies. 2942dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p> 2952dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * You may not be connected to any of this {@link Tag}'s technologies 2962dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * when calling this method. 2972dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * This method guarantees that you will be returned the same Tag 2982dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * if it is still in the field. 2992dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p>May cause RF activity and may block. Must not be called 3002dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * from the main application thread. A blocked call will be canceled with 3012dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * {@link IOException} by calling {@link #close} from another thread. 3022dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * <p>Does not remove power from the RF field, so a tag having a random 3032dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * ID should not change its ID. 3042dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * @return the rediscovered tag object. 3052dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * @throws IOException if the tag cannot be rediscovered 3062dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen * @hide 3072dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen */ 3082dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // TODO See if we need TagLostException 3092dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // TODO Unhide for ICS 3102dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // TODO Update documentation to make sure it matches with the final 3112dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen // implementation. 3122dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen public Tag rediscover() throws IOException { 3132dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen if (getConnectedTechnology() != -1) { 3142dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen throw new IllegalStateException("Close connection to the technology first!"); 3152dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 3162dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen 31723fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen if (mTagService == null) { 31823fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen throw new IOException("Mock tags don't support this operation."); 31923fc93a7c1e340e79642d3d0bf4b4658c8645c8eMartijn Coenen } 3202dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen try { 3212dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen Tag newTag = mTagService.rediscover(getServiceHandle()); 3222dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen if (newTag != null) { 3232dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen return newTag; 3242dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } else { 3252dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen throw new IOException("Failed to rediscover tag"); 3262dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 3272dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } catch (RemoteException e) { 3282dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen throw new IOException("NFC service dead"); 3292dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 3302dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen } 3312dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen 3322dcae567ab56285bc70b6857c4f3c87df09641b8Martijn Coenen 3334e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** @hide */ 3344e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public boolean hasTech(int techType) { 3354e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton for (int tech : mTechList) { 3364e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (tech == techType) return true; 3374e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 3384e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return false; 3394e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 34074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly 3414e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** @hide */ 3424e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public Bundle getTechExtras(int tech) { 3431253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen int pos = -1; 3441253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen for (int idx = 0; idx < mTechList.length; idx++) { 3451253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen if (mTechList[idx] == tech) { 3461253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen pos = idx; 3471253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen break; 3481253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen } 3491253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen } 3506be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton if (pos < 0) { 3516be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton return null; 3526be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 3536be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 3544e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return mTechExtras[pos]; 3554e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 3566be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 3574e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** @hide */ 3584e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public INfcTag getTagService() { 3594e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return mTagService; 36007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 36107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 36274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** 36374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Human-readable description of the tag, for debugging. 36474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly */ 36507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly @Override 36607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly public String toString() { 3678856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton StringBuilder sb = new StringBuilder("TAG: Tech ["); 3688856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton String[] techList = getTechList(); 3698856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton int length = techList.length; 3708856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton for (int i = 0; i < length; i++) { 3718856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton sb.append(techList[i]); 3728856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton if (i < length - 1) { 3738856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton sb.append(", "); 3748856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton } 37507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 3768856c4278d9fd727081083d0f88459a8152d88c0Jeff Hamilton sb.append("]"); 37707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return sb.toString(); 37807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 37907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 38007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /*package*/ static byte[] readBytesWithNull(Parcel in) { 38107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly int len = in.readInt(); 38207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly byte[] result = null; 383e2e4ea9ea8f5724403e6267d193a740dc7c78785Sylvain Fonteneau if (len >= 0) { 38407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly result = new byte[len]; 38507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly in.readByteArray(result); 386590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 38707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return result; 38807f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 38907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 39007f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) { 39107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly if (b == null) { 39207f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly out.writeInt(-1); 39307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly return; 39407f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly } 39507f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly out.writeInt(b.length); 39607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly out.writeByteArray(b); 397590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 398590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 399590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly @Override 400590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public int describeContents() { 401590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return 0; 402590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 403590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 404590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly @Override 405590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public void writeToParcel(Parcel dest, int flags) { 406c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau // Null mTagService means this is a mock tag 407c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau int isMock = (mTagService == null)?1:0; 408c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau 40907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly writeBytesWithNull(dest, mId); 4106be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton dest.writeInt(mTechList.length); 4116be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton dest.writeIntArray(mTechList); 4126be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton dest.writeTypedArray(mTechExtras, 0); 41307f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly dest.writeInt(mServiceHandle); 414c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau dest.writeInt(isMock); 415c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau if (isMock == 0) { 416c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau dest.writeStrongBinder(mTagService.asBinder()); 417c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau } 418590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 419590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly 420590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public static final Parcelable.Creator<Tag> CREATOR = 421590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly new Parcelable.Creator<Tag>() { 4226be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton @Override 423590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public Tag createFromParcel(Parcel in) { 424c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau INfcTag tagService; 425c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau 42607f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly // Tag fields 42707f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly byte[] id = Tag.readBytesWithNull(in); 4286be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton int[] techList = new int[in.readInt()]; 4296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton in.readIntArray(techList); 4306be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR); 43107f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly int serviceHandle = in.readInt(); 432c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau int isMock = in.readInt(); 433c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau if (isMock == 0) { 434c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau tagService = INfcTag.Stub.asInterface(in.readStrongBinder()); 435c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau } 436c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau else { 437c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau tagService = null; 438c5a418ecb7681159ae6674a4d91177c6841537b1Sylvain Fonteneau } 43907f3bee2db8b6e93ebbf7222676bd9f468e85569Nick Pelly 4404e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new Tag(id, techList, techExtras, serviceHandle, tagService); 441590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 4426be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 4436be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton @Override 444590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly public Tag[] newArray(int size) { 445590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly return new Tag[size]; 446590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly } 447590b73bc5b8e5f7b59bff1d9264a52388a5162e6Nick Pelly }; 4484049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 449be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton /** 450be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * For internal use only. 451be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * 4524049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen * @hide 4534049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen */ 4544049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen public synchronized void setConnectedTechnology(int technology) { 4554049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen if (mConnectedTechnology == -1) { 4564049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen mConnectedTechnology = technology; 4574049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } else { 4584049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen throw new IllegalStateException("Close other technology first!"); 4594049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4604049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4614049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 462be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton /** 463be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * For internal use only. 464be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * 4654049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen * @hide 4664049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen */ 4674049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen public int getConnectedTechnology() { 4684049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen return mConnectedTechnology; 4694049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4704049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen 471be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton /** 472be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * For internal use only. 473be372d6462605010910e771cef15d5adccd0a59eJeff Hamilton * 4744049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen * @hide 4754049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen */ 4764049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen public void setTechnologyDisconnected() { 4774049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen mConnectedTechnology = -1; 4784049f9d00a86f848d42d2429068496b31a6795adMartijn Coenen } 4791253ebc74a8453a88dc47a2b698145098d201681Martijn Coenen} 480