Merge "cherrypick Change-Id: I07634c137e515068911c61c04bf3e9400c3fe0d4 docs: misc changes; add path to adb tool in sdk; fix broken link to ninepatch docs; fix and add some other links" into gingerbread
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 0f96d6b..5d222d9 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -24,7 +24,7 @@
interface INfcTag
{
int close(int nativeHandle);
- int connect(int nativeHandle);
+ int connect(int nativeHandle, int technology);
int reconnect(int nativeHandle);
int[] getTechList(int nativeHandle);
byte[] getUid(int nativeHandle);
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index d042634..7404950 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -63,6 +63,8 @@
/*package*/ final Bundle[] mTechExtras;
/*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
+ /*package*/ int mConnectedTechnology;
+
/**
* Hidden constructor to be used by NFC service and internal classes.
* @hide
@@ -76,6 +78,8 @@
// Ensure mTechExtras is as long as mTechList
mTechExtras = Arrays.copyOf(techListExtras, techList.length);
mServiceHandle = serviceHandle;
+
+ mConnectedTechnology = -1;
}
/**
@@ -244,4 +248,29 @@
return new Tag[size];
}
};
+
+ /*
+ * @hide
+ */
+ public synchronized void setConnectedTechnology(int technology) {
+ if (mConnectedTechnology == -1) {
+ mConnectedTechnology = technology;
+ } else {
+ throw new IllegalStateException("Close other technology first!");
+ }
+ }
+
+ /*
+ * @hide
+ */
+ public int getConnectedTechnology() {
+ return mConnectedTechnology;
+ }
+
+ /*
+ * @hide
+ */
+ public void setTechnologyDisconnected() {
+ mConnectedTechnology = -1;
+ }
}
diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java
index a50c10b..553f6ec 100644
--- a/core/java/android/nfc/technology/BasicTagTechnology.java
+++ b/core/java/android/nfc/technology/BasicTagTechnology.java
@@ -22,6 +22,7 @@
import android.nfc.INfcTag;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
+import android.nfc.ErrorCodes;
import android.os.RemoteException;
import android.util.Log;
@@ -101,6 +102,13 @@
return mTag;
}
+ public void checkConnected() {
+ if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
+ (mTag.getConnectedTechnology() == -1)) {
+ throw new IllegalStateException("Call connect() first!");
+ }
+ }
+
/**
* <p>Requires {@link android.Manifest.permission#NFC} permission.
*/
@@ -144,8 +152,53 @@
*/
@Override
public void connect() throws IOException {
- //TODO(nxp): enforce exclusivity
- mIsConnected = true;
+ try {
+ int errorCode = mTagService.connect(mTag.getServiceHandle(), getTechnologyId());
+
+ if (errorCode == ErrorCodes.SUCCESS) {
+ // Store this in the tag object
+ mTag.setConnectedTechnology(getTechnologyId());
+ mIsConnected = true;
+ } else {
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ throw new IOException("NFC service died");
+ }
+ }
+
+ /**
+ * Re-connect to the {@link Tag} associated with this connection.
+ * <p>
+ * Reconnecting to a tag can be used to reset the state of the tag itself.
+ * This method blocks until the connection is re-established.
+ * <p>
+ * {@link #close} can be called from another thread to cancel this connection
+ * attempt.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ * @throws IOException if the target is lost, or connect canceled
+ */
+ @Override
+ public void reconnect() throws IOException {
+ if (!mIsConnected) {
+ throw new IllegalStateException("Technology not connected yet");
+ } else {
+ try {
+ int errorCode = mTagService.reconnect(mTag.getServiceHandle());
+
+ if (errorCode != ErrorCodes.SUCCESS) {
+ mIsConnected = false;
+ mTag.setTechnologyDisconnected();
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ mIsConnected = false;
+ mTag.setTechnologyDisconnected();
+ attemptDeadServiceRecovery(e);
+ throw new IOException("NFC service died");
+ }
+ }
}
/**
@@ -160,7 +213,6 @@
*/
@Override
public void close() {
- mIsConnected = false;
try {
/* Note that we don't want to physically disconnect the tag,
* but just reconnect to it to reset its state
@@ -168,6 +220,9 @@
mTagService.reconnect(mTag.getServiceHandle());
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
+ } finally {
+ mIsConnected = false;
+ mTag.setTechnologyDisconnected();
}
}
@@ -183,6 +238,8 @@
* @throws IOException if the target is lost or connection closed
*/
public byte[] transceive(byte[] data) throws IOException {
+ checkConnected();
+
try {
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, true);
if (response == null) {
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
index 5346c67..118bff7 100644
--- a/core/java/android/nfc/technology/IsoDep.java
+++ b/core/java/android/nfc/technology/IsoDep.java
@@ -75,6 +75,8 @@
* @throws IOException, UnsupportedOperationException
*/
public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException {
+ checkConnected();
+
throw new UnsupportedOperationException();
}
}
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
index defdcf2..d5f0a31 100644
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -229,6 +229,8 @@
* Authenticate for a given sector.
*/
public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
+ checkConnected();
+
byte[] cmd = new byte[12];
// First byte is the command
@@ -264,6 +266,8 @@
* @throws IOException
*/
public byte[] readBlock(int sector, int block) throws IOException {
+ checkConnected();
+
byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead
@@ -300,6 +304,8 @@
*/
@Override
public byte[] transceive(byte[] data) throws IOException {
+ checkConnected();
+
try {
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
if (response == null) {
diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java
index 58d2645..7103b4d 100644
--- a/core/java/android/nfc/technology/MifareUltralight.java
+++ b/core/java/android/nfc/technology/MifareUltralight.java
@@ -66,11 +66,44 @@
* @throws IOException
*/
public byte[] readBlock(int block) throws IOException {
+ checkConnected();
+
byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead
return transceive(blockread_cmd);
}
/**
+ * @throws IOException
+ */
+ public byte[] readOTP() throws IOException {
+ checkConnected();
+
+ return readBlock(3); // OTP is at page 3
+ }
+
+ public void writePage(int block, byte[] data) throws IOException {
+ checkConnected();
+
+ byte[] pagewrite_cmd = new byte[data.length + 2];
+ pagewrite_cmd[0] = (byte) 0xA2;
+ pagewrite_cmd[1] = (byte) block;
+ System.arraycopy(data, 0, pagewrite_cmd, 2, data.length);
+
+ transceive(pagewrite_cmd);
+ }
+
+ public void writeBlock(int block, byte[] data) throws IOException {
+ checkConnected();
+
+ byte[] blockwrite_cmd = new byte[data.length + 2];
+ blockwrite_cmd[0] = (byte) 0xA0;
+ blockwrite_cmd[1] = (byte) block;
+ System.arraycopy(data, 0, blockwrite_cmd, 2, data.length);
+
+ transceive(blockwrite_cmd);
+ }
+
+ /**
* Send data to a tag and receive the response.
* <p>
* This method will block until the response is received. It can be canceled
@@ -83,6 +116,8 @@
*/
@Override
public byte[] transceive(byte[] data) throws IOException {
+ checkConnected();
+
try {
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
if (response == null) {
@@ -95,12 +130,4 @@
}
}
- /**
- * @throws IOException
- */
- /*
- public byte[] readOTP();
- public void writePage(int block, byte[] data);
- public void writeBlock(int block, byte[] data);
- */
}
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index 7e194aa..c45c97d 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -113,6 +113,8 @@
* and requires a connection.
*/
public NdefMessage getNdefMessage() throws IOException, FormatException {
+ checkConnected();
+
try {
int serviceHandle = mTag.getServiceHandle();
if (mTagService.isNdef(serviceHandle)) {
@@ -143,6 +145,8 @@
* @throws IOException
*/
public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
+ checkConnected();
+
try {
int errorCode = mTagService.ndefWrite(mTag.getServiceHandle(), msg);
switch (errorCode) {
@@ -172,6 +176,8 @@
* @throws IOException
*/
public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
+ checkConnected();
+
throw new UnsupportedOperationException();
}
@@ -180,6 +186,8 @@
* @throws IOException
*/
public boolean makeReadonly() throws IOException {
+ checkConnected();
+
try {
int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
switch (errorCode) {
@@ -205,11 +213,15 @@
* For NFC Forum Type 1 and 2 only.
*/
public void makeLowLevelReadonly() {
+ checkConnected();
+
throw new UnsupportedOperationException();
}
@Override
public byte[] transceive(byte[] data) {
+ checkConnected();
+
throw new UnsupportedOperationException();
}
}
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
index bd21e58..899b95f 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -49,7 +49,9 @@
* NdefFormatable#format(NdefMessage)}
*/
public boolean canBeFormatted() throws IOException {
- throw new UnsupportedOperationException();
+ checkConnected();
+
+ throw new UnsupportedOperationException();
}
/**
@@ -57,6 +59,8 @@
* NdefMessage to be written on the tag.
*/
public void format(NdefMessage firstMessage) throws IOException, FormatException {
+ checkConnected();
+
try {
byte[] DEFAULT_KEY = {(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xFF,(byte)0xFF,(byte)0xFF};
@@ -97,6 +101,8 @@
@Override
public byte[] transceive(byte[] data) {
+ checkConnected();
+
throw new UnsupportedOperationException();
}
}
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
index bef1cc4..62216c1 100644
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -82,6 +82,11 @@
public void connect() throws IOException;
/**
+ * @throws IOException
+ */
+ public void reconnect() throws IOException;
+
+ /**
* Non-blocking. Immediately causes all blocking calls
* to throw IOException.
*/