summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-02-11 12:42:43 -0800
committerMartijn Coenen <maco@google.com>2013-02-12 13:37:56 -0800
commitc3981b9a0b39faed474480bc3dbd3e33bbd50b99 (patch)
tree48d8337a051ee5a86753ac0f5ed71ed4d50273b4
parent97fe497ede803f09d45253ee5fba51bf03cb724a (diff)
downloadandroid_packages_apps_Nfc-c3981b9a0b39faed474480bc3dbd3e33bbd50b99.tar.gz
android_packages_apps_Nfc-c3981b9a0b39faed474480bc3dbd3e33bbd50b99.tar.bz2
android_packages_apps_Nfc-c3981b9a0b39faed474480bc3dbd3e33bbd50b99.zip
Return more accurate errors for NfcEe.open.
There are a number of different conditions under which access to the SE is not possible. Since some of these require user intervention to resolve (ie external field present), return a more accurate reason for NfcEe.open failure. Bug: 4304698 Change-Id: Ie947c29be12d554a02d9246264a9f0e026a37af8
-rwxr-xr-xnci/jni/NativeSecureElement.cpp17
-rw-r--r--nxp/jni/com_android_nfc.h9
-rwxr-xr-xnxp/jni/com_android_nfc_NativeNfcSecureElement.cpp7
-rwxr-xr-xsrc/com/android/nfc/NfcService.java46
4 files changed, 61 insertions, 18 deletions
diff --git a/nci/jni/NativeSecureElement.cpp b/nci/jni/NativeSecureElement.cpp
index d1438bcd..fea2e151 100755
--- a/nci/jni/NativeSecureElement.cpp
+++ b/nci/jni/NativeSecureElement.cpp
@@ -27,6 +27,13 @@ extern void com_android_nfc_NfcManager_disableDiscovery (JNIEnv* e, jobject o);
extern void com_android_nfc_NfcManager_enableDiscovery (JNIEnv* e, jobject o, jint mode);
extern int gGeneralTransceiveTimeout;
+// These must match the EE_ERROR_ types in NfcService.java
+static const int EE_ERROR_IO = -1;
+static const int EE_ERROR_ALREADY_OPEN = -2;
+static const int EE_ERROR_INIT = -3;
+static const int EE_ERROR_LISTEN_MODE = -4;
+static const int EE_ERROR_EXT_FIELD = -5;
+static const int EE_ERROR_NFC_DISABLED = -6;
/*******************************************************************************
**
@@ -36,23 +43,25 @@ extern int gGeneralTransceiveTimeout;
** e: JVM environment.
** o: Java object.
**
-** Returns: Handle of secure element. 0 is failure.
+** Returns: Handle of secure element. values < 0 represent failure.
**
*******************************************************************************/
static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobject)
{
ALOGD("%s: enter", __FUNCTION__);
bool stat = true;
- jint secElemHandle = 0;
+ jint secElemHandle = EE_ERROR_INIT;
SecureElement &se = SecureElement::getInstance();
if (se.isActivatedInListenMode()) {
ALOGD("Denying SE open due to SE listen mode active");
+ secElemHandle = EE_ERROR_LISTEN_MODE;
goto TheEnd;
}
if (se.isRfFieldOn()) {
ALOGD("Denying SE open due to SE in active RF field");
+ secElemHandle = EE_ERROR_EXT_FIELD;
goto TheEnd;
}
//tell the controller to power up to get ready for sec elem operations
@@ -69,9 +78,13 @@ static jint nativeNfcSecureElement_doOpenSecureElementConnection (JNIEnv*, jobje
//establish a pipe to sec elem
stat = se.connectEE();
if (stat)
+ {
secElemHandle = se.mActiveEeHandle;
+ }
else
+ {
se.deactivate (0);
+ }
}
//if code fails to connect to the secure element, and nothing is active, then
diff --git a/nxp/jni/com_android_nfc.h b/nxp/jni/com_android_nfc.h
index 56c229f1..1eed2049 100644
--- a/nxp/jni/com_android_nfc.h
+++ b/nxp/jni/com_android_nfc.h
@@ -105,6 +105,15 @@ extern "C" {
#define SMX_SECURE_ELEMENT_ID 11259375
+
+/* These must match the EE_ERROR_ types in NfcService.java */
+#define EE_ERROR_IO -1
+#define EE_ERROR_ALREADY_OPEN -2
+#define EE_ERROR_INIT -3
+#define EE_ERROR_LISTEN_MODE -4
+#define EE_ERROR_EXT_FIELD -5
+#define EE_ERROR_NFC_DISABLED -6
+
/* Maximum byte length of an AID. */
#define AID_MAXLEN 16
diff --git a/nxp/jni/com_android_nfc_NativeNfcSecureElement.cpp b/nxp/jni/com_android_nfc_NativeNfcSecureElement.cpp
index 79887a0e..9e0a6e23 100755
--- a/nxp/jni/com_android_nfc_NativeNfcSecureElement.cpp
+++ b/nxp/jni/com_android_nfc_NativeNfcSecureElement.cpp
@@ -179,6 +179,7 @@ static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection
{
NFCSTATUS ret;
int semResult;
+ jint errorCode = EE_ERROR_INIT;
phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index=0, SmartMX_detected = 0;
@@ -224,7 +225,8 @@ static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection
/* Check if NFC device is already connected to a tag or P2P peer */
if (device_connected_flag == 1)
{
- ALOGD("Unable to open SE connection, device already connected to a P2P peer or a Tag");
+ ALOGE("Unable to open SE connection, device already connected to a P2P peer or a Tag");
+ errorCode = EE_ERROR_LISTEN_MODE;
goto clean_and_return;
}
@@ -263,6 +265,7 @@ static jint com_android_nfc_NativeNfcSecureElement_doOpenSecureElementConnection
{
// There is an external RF field present, fail the open request
ALOGD("Unable to open SE connection, external RF Field detected");
+ errorCode = EE_ERROR_EXT_FIELD;
goto clean_and_return;
}
@@ -464,7 +467,7 @@ clean_and_return:
nfc_cb_data_deinit(&cb_data_SE_Notification);
CONCURRENCY_UNLOCK();
- return 0;
+ return errorCode;
}
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index 27913079..44369274 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -132,6 +132,15 @@ public class NfcService implements DeviceHostListener {
static final int ROUTE_OFF = 1;
static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
+ // Return values from NfcEe.open() - these are 1:1 mapped
+ // to the thrown EE_EXCEPTION_ exceptions in nfc-extras.
+ static final int EE_ERROR_IO = -1;
+ static final int EE_ERROR_ALREADY_OPEN = -2;
+ static final int EE_ERROR_INIT = -3;
+ static final int EE_ERROR_LISTEN_MODE = -4;
+ static final int EE_ERROR_EXT_FIELD = -5;
+ static final int EE_ERROR_NFC_DISABLED = -6;
+
/** minimum screen state that enables NFC polling (discovery) */
static final int POLLING_MODE = SCREEN_STATE_ON_UNLOCKED;
@@ -1297,10 +1306,11 @@ public class NfcService implements DeviceHostListener {
p.putInt("e", 0);
return p;
}
- private Bundle writeIoException(IOException e) {
+
+ private Bundle writeEeException(int exceptionType, String message) {
Bundle p = new Bundle();
- p.putInt("e", -1);
- p.putString("m", e.getMessage());
+ p.putInt("e", exceptionType);
+ p.putString("m", message);
return p;
}
@@ -1309,27 +1319,33 @@ public class NfcService implements DeviceHostListener {
NfcService.this.enforceNfceeAdminPerm(pkg);
Bundle result;
- try {
- _open(b);
+ int handle = _open(b);
+ if (handle < 0) {
+ result = writeEeException(handle, "NFCEE open exception.");
+ } else {
result = writeNoException();
- } catch (IOException e) {
- result = writeIoException(e);
}
return result;
}
- private void _open(IBinder b) throws IOException {
+ /**
+ * Opens a connection to the secure element.
+ *
+ * @return A handle with a value >= 0 in case of success, or a
+ * negative value in case of failure.
+ */
+ private int _open(IBinder b) {
synchronized(NfcService.this) {
if (!isNfcEnabled()) {
- throw new IOException("NFC adapter is disabled");
+ return EE_ERROR_NFC_DISABLED;
}
if (mOpenEe != null) {
- throw new IOException("NFC EE already open");
+ return EE_ERROR_ALREADY_OPEN;
}
int handle = doOpenSecureElementConnection();
- if (handle == 0) {
- throw new IOException("NFC EE failed to open");
+ if (handle < 0) {
+ return handle;
}
mDeviceHost.setTimeout(TagTechnology.ISO_DEP, 30000);
@@ -1345,6 +1361,8 @@ public class NfcService implements DeviceHostListener {
for (String packageName : mContext.getPackageManager().getPackagesForUid(getCallingUid())) {
mSePackages.add(packageName);
}
+
+ return handle;
}
}
@@ -1357,7 +1375,7 @@ public class NfcService implements DeviceHostListener {
_nfcEeClose(getCallingPid(), binder);
result = writeNoException();
} catch (IOException e) {
- result = writeIoException(e);
+ result = writeEeException(EE_ERROR_IO, e.getMessage());
}
return result;
}
@@ -1373,7 +1391,7 @@ public class NfcService implements DeviceHostListener {
result = writeNoException();
result.putByteArray("out", out);
} catch (IOException e) {
- result = writeIoException(e);
+ result = writeEeException(EE_ERROR_IO, e.getMessage());
}
return result;
}