HCE: Fix potential crash and handle Android AID.
For new "default route" CTS test. Also, fix
a potential crash for starting off-host services
and check that HCE services have declared the
NFC permission.
Bug: 10681671
Change-Id: If86d9820d6eef5a0661be92be67168d5f81ddc64
diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java
index 0dc75b5..a4e7f75 100644
--- a/src/com/android/nfc/cardemulation/HostEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java
@@ -60,6 +60,9 @@
static final byte INSTR_SELECT = (byte)0xA4;
+ static final String ANDROID_HCE_AID = "A000000476416E64726F6964484345";
+ static final byte[] ANDROID_HCE_RESPONSE = {0x14, (byte)0x81, 0x00, 0x00, (byte)0x90, 0x00};
+
static final byte[] AID_NOT_FOUND = {0x6A, (byte)0x82};
static final byte[] UNKNOWN_ERROR = {0x6F, 0x00};
@@ -161,6 +164,10 @@
return;
}
if (selectAid != null) {
+ if (selectAid.equals(ANDROID_HCE_AID)) {
+ NfcService.getInstance().sendData(ANDROID_HCE_RESPONSE);
+ return;
+ }
AidResolveInfo resolveInfo = mAidCache.resolveAidPrefix(selectAid);
if (resolveInfo == null || resolveInfo.services.size() == 0) {
// Tell the remote we don't handle this AID
@@ -179,6 +186,14 @@
launchTapAgain(resolveInfo.defaultService, category);
return;
}
+ // In no circumstance should this be an OffHostService -
+ // we should never get this AID on the host in the first place
+ if (!resolveInfo.defaultService.isOnHost()) {
+ Log.e(TAG, "AID that was meant to go off-host was routed to host." +
+ " Check routing table configuration.");
+ NfcService.getInstance().sendData(AID_NOT_FOUND);
+ return;
+ }
resolvedService = resolveInfo.defaultService.getComponent();
} else if (mActiveServiceName != null) {
for (ApduServiceInfo service : resolveInfo.services) {
diff --git a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
index 2e037d2..0cfc0e0 100644
--- a/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredServicesCache.java
@@ -207,6 +207,14 @@
boolean onHost = !resolvedOffHostServices.contains(resolvedService);
ServiceInfo si = resolvedService.serviceInfo;
ComponentName componentName = new ComponentName(si.packageName, si.name);
+ // Check if the package holds the NFC permission
+ if (pm.checkPermission(android.Manifest.permission.NFC, si.packageName) !=
+ PackageManager.PERMISSION_GRANTED) {
+ Log.e(TAG, "Skipping APDU service " + componentName +
+ ": it does not require the permission " +
+ android.Manifest.permission.NFC);
+ continue;
+ }
if (!android.Manifest.permission.BIND_NFC_SERVICE.equals(
si.permission)) {
Log.e(TAG, "Skipping APDU service " + componentName +