From faca12adc62d148505fadfd286e6a2752c197fa0 Mon Sep 17 00:00:00 2001 From: Martijn Coenen Date: Fri, 19 Aug 2011 14:07:52 +0200 Subject: [PATCH] Add getMaxTransceiveLength() API. Also moved canMakeReadOnly() down in the stack, and cleaned up TransceiveResult. Change-Id: I85576c52478ab79f0726606659b0c17d00b222e6 --- api/current.txt | 7 +++ core/java/android/nfc/INfcTag.aidl | 2 + core/java/android/nfc/TransceiveResult.java | 51 ++++++++++--------- .../android/nfc/tech/BasicTagTechnology.java | 20 ++++---- core/java/android/nfc/tech/IsoDep.java | 11 ++++ core/java/android/nfc/tech/MifareClassic.java | 11 ++++ .../android/nfc/tech/MifareUltralight.java | 11 ++++ core/java/android/nfc/tech/Ndef.java | 8 +-- core/java/android/nfc/tech/NfcA.java | 11 ++++ core/java/android/nfc/tech/NfcB.java | 11 ++++ core/java/android/nfc/tech/NfcF.java | 11 ++++ core/java/android/nfc/tech/NfcV.java | 12 +++++ 12 files changed, 129 insertions(+), 37 deletions(-) diff --git a/api/current.txt b/api/current.txt index 033cccbe33567..9e304bc13614f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12441,6 +12441,7 @@ package android.nfc.tech { method public static android.nfc.tech.IsoDep get(android.nfc.Tag); method public byte[] getHiLayerResponse(); method public byte[] getHistoricalBytes(); + method public int getMaxTransceiveLength(); method public void setTimeout(int); method public byte[] transceive(byte[]) throws java.io.IOException; } @@ -12453,6 +12454,7 @@ package android.nfc.tech { method public static android.nfc.tech.MifareClassic get(android.nfc.Tag); method public int getBlockCount(); method public int getBlockCountInSector(int); + method public int getMaxTransceiveLength(); method public int getSectorCount(); method public int getSize(); method public int getType(); @@ -12479,6 +12481,7 @@ package android.nfc.tech { public final class MifareUltralight extends android.nfc.tech.BasicTagTechnology { method public static android.nfc.tech.MifareUltralight get(android.nfc.Tag); + method public int getMaxTransceiveLength(); method public int getType(); method public byte[] readPages(int) throws java.io.IOException; method public byte[] transceive(byte[]) throws java.io.IOException; @@ -12515,6 +12518,7 @@ package android.nfc.tech { public final class NfcA extends android.nfc.tech.BasicTagTechnology { method public static android.nfc.tech.NfcA get(android.nfc.Tag); method public byte[] getAtqa(); + method public int getMaxTransceiveLength(); method public short getSak(); method public byte[] transceive(byte[]) throws java.io.IOException; } @@ -12522,6 +12526,7 @@ package android.nfc.tech { public final class NfcB extends android.nfc.tech.BasicTagTechnology { method public static android.nfc.tech.NfcB get(android.nfc.Tag); method public byte[] getApplicationData(); + method public int getMaxTransceiveLength(); method public byte[] getProtocolInfo(); method public byte[] transceive(byte[]) throws java.io.IOException; } @@ -12529,6 +12534,7 @@ package android.nfc.tech { public final class NfcF extends android.nfc.tech.BasicTagTechnology { method public static android.nfc.tech.NfcF get(android.nfc.Tag); method public byte[] getManufacturer(); + method public int getMaxTransceiveLength(); method public byte[] getSystemCode(); method public byte[] transceive(byte[]) throws java.io.IOException; } @@ -12536,6 +12542,7 @@ package android.nfc.tech { public final class NfcV extends android.nfc.tech.BasicTagTechnology { method public static android.nfc.tech.NfcV get(android.nfc.Tag); method public byte getDsfId(); + method public int getMaxTransceiveLength(); method public byte getResponseFlags(); method public byte[] transceive(byte[]) throws java.io.IOException; } diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl index 7bdefe7b0eb7b..bb5a9fd32e6d7 100644 --- a/core/java/android/nfc/INfcTag.aidl +++ b/core/java/android/nfc/INfcTag.aidl @@ -46,4 +46,6 @@ interface INfcTag int setTimeout(int technology, int timeout); int getTimeout(int technology); void resetTimeouts(); + boolean canMakeReadOnly(int ndefType); + int getMaxTransceiveLength(int technology); } diff --git a/core/java/android/nfc/TransceiveResult.java b/core/java/android/nfc/TransceiveResult.java index 16244b8fe6227..353882541b1b9 100644 --- a/core/java/android/nfc/TransceiveResult.java +++ b/core/java/android/nfc/TransceiveResult.java @@ -19,33 +19,38 @@ package android.nfc; import android.os.Parcel; import android.os.Parcelable; +import java.io.IOException; + /** * Class used to pipe transceive result from the NFC service. * * @hide */ public final class TransceiveResult implements Parcelable { - private final boolean mTagLost; - private final boolean mSuccess; - private final byte[] mResponseData; + public static final int RESULT_SUCCESS = 0; + public static final int RESULT_FAILURE = 1; + public static final int RESULT_TAGLOST = 2; + public static final int RESULT_EXCEEDED_LENGTH = 3; - public TransceiveResult(final boolean success, final boolean tagIsLost, - final byte[] data) { - mSuccess = success; - mTagLost = tagIsLost; + final int mResult; + final byte[] mResponseData; + + public TransceiveResult(final int result, final byte[] data) { + mResult = result; mResponseData = data; } - public boolean isSuccessful() { - return mSuccess; - } - - public boolean isTagLost() { - return mTagLost; - } - - public byte[] getResponseData() { - return mResponseData; + public byte[] getResponseOrThrow() throws IOException { + switch (mResult) { + case RESULT_SUCCESS: + return mResponseData; + case RESULT_TAGLOST: + throw new TagLostException("Tag was lost."); + case RESULT_EXCEEDED_LENGTH: + throw new IOException("Transceive length exceeds supported maximum"); + default: + throw new IOException("Transceive failed"); + } } @Override @@ -55,9 +60,8 @@ public final class TransceiveResult implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mSuccess ? 1 : 0); - dest.writeInt(mTagLost ? 1 : 0); - if (mSuccess) { + dest.writeInt(mResult); + if (mResult == RESULT_SUCCESS) { dest.writeInt(mResponseData.length); dest.writeByteArray(mResponseData); } @@ -67,18 +71,17 @@ public final class TransceiveResult implements Parcelable { new Parcelable.Creator() { @Override public TransceiveResult createFromParcel(Parcel in) { - boolean success = (in.readInt() == 1) ? true : false; - boolean tagLost = (in.readInt() == 1) ? true : false; + int result = in.readInt(); byte[] responseData; - if (success) { + if (result == RESULT_SUCCESS) { int responseLength = in.readInt(); responseData = new byte[responseLength]; in.readByteArray(responseData); } else { responseData = null; } - return new TransceiveResult(success, tagLost, responseData); + return new TransceiveResult(result, responseData); } @Override diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java index bcb7199f0a58e..913ae0eccda62 100644 --- a/core/java/android/nfc/tech/BasicTagTechnology.java +++ b/core/java/android/nfc/tech/BasicTagTechnology.java @@ -129,6 +129,15 @@ import java.io.IOException; } } + /** Internal getMaxTransceiveLength() */ + int getMaxTransceiveLengthInternal() { + try { + return mTag.getTagService().getMaxTransceiveLength(mSelectedTechnology); + } catch (RemoteException e) { + Log.e(TAG, "NFC service dead", e); + return 0; + } + } /** Internal transceive */ /*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException { checkConnected(); @@ -139,16 +148,7 @@ import java.io.IOException; if (result == null) { throw new IOException("transceive failed"); } else { - if (result.isSuccessful()) { - return result.getResponseData(); - } else { - if (result.isTagLost()) { - throw new TagLostException("Tag was lost."); - } - else { - throw new IOException("transceive failed"); - } - } + return result.getResponseOrThrow(); } } catch (RemoteException e) { Log.e(TAG, "NFC service dead", e); diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java index 0672a4eba281f..6054fe8ce9342 100644 --- a/core/java/android/nfc/tech/IsoDep.java +++ b/core/java/android/nfc/tech/IsoDep.java @@ -156,6 +156,9 @@ public final class IsoDep extends BasicTagTechnology { * will be automatically fragmented and defragmented by {@link #transceive} if * it exceeds FSD/FSC limits. * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -170,4 +173,12 @@ public final class IsoDep extends BasicTagTechnology { public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); } + + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } } diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java index 93e7cbddec944..ce923aeefa77b 100644 --- a/core/java/android/nfc/tech/MifareClassic.java +++ b/core/java/android/nfc/tech/MifareClassic.java @@ -560,6 +560,9 @@ public final class MifareClassic extends BasicTagTechnology { * and calling {@link NfcA#transceive}. Note that all MIFARE Classic * tags are based on {@link NfcA} technology. * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -572,6 +575,14 @@ public final class MifareClassic extends BasicTagTechnology { return transceive(data, true); } + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } + /** * Set the timeout of {@link #transceive} in milliseconds. *

The timeout only applies to MifareUltralight {@link #transceive}, diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java index ca74ebe521c91..890b73583967b 100644 --- a/core/java/android/nfc/tech/MifareUltralight.java +++ b/core/java/android/nfc/tech/MifareUltralight.java @@ -200,6 +200,9 @@ public final class MifareUltralight extends BasicTagTechnology { * and calling {@link NfcA#transceive}. Note that all MIFARE Classic * tags are based on {@link NfcA} technology. * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -212,6 +215,14 @@ public final class MifareUltralight extends BasicTagTechnology { return transceive(data, true); } + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } + /** * Set the timeout of {@link #transceive} in milliseconds. *

The timeout only applies to MifareUltralight {@link #transceive}, diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index e4daa57821881..b266bb6dd1edc 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -334,9 +334,11 @@ public final class Ndef extends BasicTagTechnology { * @return true if it is possible to make this tag read-only */ public boolean canMakeReadOnly() { - if (mNdefType == TYPE_1 || mNdefType == TYPE_2) { - return true; - } else { + INfcTag tagService = mTag.getTagService(); + try { + return tagService.canMakeReadOnly(mNdefType); + } catch (RemoteException e) { + Log.e(TAG, "NFC service dead", e); return false; } } diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java index bd1f95af63ec0..bb8aec9ca6bf1 100644 --- a/core/java/android/nfc/tech/NfcA.java +++ b/core/java/android/nfc/tech/NfcA.java @@ -102,6 +102,9 @@ public final class NfcA extends BasicTagTechnology { * for example a SENS_REQ is not possible (these are used to * manage tag polling and initialization). * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -117,6 +120,14 @@ public final class NfcA extends BasicTagTechnology { return transceive(data, true); } + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } + /** * Set the timeout of {@link #transceive} in milliseconds. *

The timeout only applies to NfcA {@link #transceive}, and is diff --git a/core/java/android/nfc/tech/NfcB.java b/core/java/android/nfc/tech/NfcB.java index 22cb11dd4763c..3ebd47f610c0d 100644 --- a/core/java/android/nfc/tech/NfcB.java +++ b/core/java/android/nfc/tech/NfcB.java @@ -97,6 +97,9 @@ public final class NfcB extends BasicTagTechnology { *

Applications must not send commands that manage the polling * loop and initialization (SENSB_REQ, SLOT_MARKER etc). * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -111,4 +114,12 @@ public final class NfcB extends BasicTagTechnology { public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); } + + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } } diff --git a/core/java/android/nfc/tech/NfcF.java b/core/java/android/nfc/tech/NfcF.java index 7b25a72231b97..0938fb401e12a 100644 --- a/core/java/android/nfc/tech/NfcF.java +++ b/core/java/android/nfc/tech/NfcF.java @@ -101,6 +101,9 @@ public final class NfcF extends BasicTagTechnology { *

Applications must not append the SoD (length) or EoD (CRC) to the payload, * it will be automatically calculated. * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -116,6 +119,14 @@ public final class NfcF extends BasicTagTechnology { return transceive(data, true); } + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } + /** * Set the timeout of {@link #transceive} in milliseconds. *

The timeout only applies to NfcF {@link #transceive}, and is diff --git a/core/java/android/nfc/tech/NfcV.java b/core/java/android/nfc/tech/NfcV.java index fe721c88b0489..186c63bf07fd1 100644 --- a/core/java/android/nfc/tech/NfcV.java +++ b/core/java/android/nfc/tech/NfcV.java @@ -97,6 +97,9 @@ public final class NfcV extends BasicTagTechnology { * it will be automatically calculated. The application does * provide FLAGS, CMD and PARAMETER bytes. * + *

Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes + * that can be sent with {@link #transceive}. + * *

This is an I/O operation and will block until complete. It must * not be called from the main application thread. A blocked call will be canceled with * {@link IOException} if {@link #close} is called from another thread. @@ -111,4 +114,13 @@ public final class NfcV extends BasicTagTechnology { public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); } + + + /** + * Return the maximum number of bytes that can be sent with {@link #transceive}. + * @return the maximum number of bytes that can be sent with {@link #transceive}. + */ + public int getMaxTransceiveLength() { + return getMaxTransceiveLengthInternal(); + } }