summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndres Morales <anmorales@google.com>2013-12-18 13:07:41 -0800
committerAndres Morales <anmorales@google.com>2014-06-25 21:22:52 +0000
commit0799bcbe2469aa6a88c6cbdf0cdee5b50e1994f0 (patch)
tree14874176d7e6ca3cbb7e658f8962e14dc37f2e58
parente4ec1c146b3c765f9d0ae9ad7dae9b625d764076 (diff)
downloadandroid_packages_apps_Nfc-0799bcbe2469aa6a88c6cbdf0cdee5b50e1994f0.tar.gz
android_packages_apps_Nfc-0799bcbe2469aa6a88c6cbdf0cdee5b50e1994f0.tar.bz2
android_packages_apps_Nfc-0799bcbe2469aa6a88c6cbdf0cdee5b50e1994f0.zip
Refactoring NfcService routing logic.
Currently, routing logic contains a lot of nested conditionals and causes unnecessary work to occur, particularly in enabling reader mode. This CL moves this logic to a state object that contains all necessary information to transfer from one routing state to another, leading to fewer calls to the NFCC, eliminating duplicate work, and making the code more readable. Change-Id: I6a8758e61cc0cbb015d618575da35386eadf7d3a
-rwxr-xr-xnci/jni/NativeNfcManager.cpp321
-rw-r--r--nci/jni/RoutingManager.cpp77
-rw-r--r--nci/jni/RoutingManager.h3
-rwxr-xr-xnci/src/com/android/nfc/dhimpl/NativeNfcManager.java37
-rw-r--r--nxp/jni/com_android_nfc_NativeNfcManager.cpp80
-rwxr-xr-xnxp/src/com/android/nfc/dhimpl/NativeNfcManager.java39
-rw-r--r--src/com/android/nfc/DeviceHost.java12
-rw-r--r--src/com/android/nfc/NfcDiscoveryParameters.java139
-rwxr-xr-xsrc/com/android/nfc/NfcService.java190
9 files changed, 395 insertions, 503 deletions
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp
index 91e2faf2..e80c1cb1 100755
--- a/nci/jni/NativeNfcManager.cpp
+++ b/nci/jni/NativeNfcManager.cpp
@@ -93,7 +93,6 @@ namespace android
void doStartupConfig ();
void startStopPolling (bool isStartPolling);
void startRfDiscovery (bool isStart);
- void restartPollingWithTechMask(int mask);
}
@@ -115,14 +114,14 @@ static SyncEvent sNfaEnableDisablePollingEvent; //event for NFA_Enab
static SyncEvent sNfaSetConfigEvent; // event for Set_Config....
static SyncEvent sNfaGetConfigEvent; // event for Get_Config....
static bool sIsNfaEnabled = false;
-static bool sDiscoveryEnabled = false; //is polling for tag?
+static bool sDiscoveryEnabled = false; //is polling or listening
+static bool sPollingEnabled = false; //is polling for tag?
static bool sIsDisabling = false;
static bool sRfEnabled = false; // whether RF discovery is enabled
static bool sSeRfActive = false; // whether RF with SE is likely active
static bool sReaderModeEnabled = false; // whether we're only reading tags, not allowing P2p/card emu
static bool sP2pActive = false; // whether p2p was last active
static bool sAbortConnlessWait = false;
-static bool sIsSecElemSelected = false; //has NFC service selected a sec elem
#define CONFIG_UPDATE_TECH_MASK (1 << 1)
#define DEFAULT_TECH_MASK (NFA_TECHNOLOGY_MASK_A \
| NFA_TECHNOLOGY_MASK_B \
@@ -140,6 +139,8 @@ static void nfaDeviceManagementCallback (UINT8 event, tNFA_DM_CBACK_DATA *eventD
static bool isPeerToPeer (tNFA_ACTIVATED& activated);
static bool isListenMode(tNFA_ACTIVATED& activated);
static void enableDisableLptd (bool enable);
+static tNFA_STATUS stopPolling_rfDiscoveryDisabled();
+static tNFA_STATUS startPolling_rfDiscoveryDisabled(tNFA_TECHNOLOGY_MASK tech_mask);
static UINT16 sCurrentConfigLen;
static UINT8 sConfig[256];
@@ -676,6 +677,7 @@ void nfaDeviceManagementCallback (UINT8 dmEvent, tNFA_DM_CBACK_DATA* eventData)
sNfaDisableEvent.notifyOne();
}
sDiscoveryEnabled = false;
+ sPollingEnabled = false;
PowerSwitch::getInstance ().abort ();
if (!sIsDisabling && sIsNfaEnabled)
@@ -896,28 +898,26 @@ TheEnd:
**
*******************************************************************************/
static void nfcManager_enableDiscovery (JNIEnv* e, jobject o, jint technologies_mask, \
- jboolean enable_lptd)
+ jboolean enable_lptd, jboolean reader_mode, jboolean enable_host_routing,
+ jboolean restart)
{
tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
struct nfc_jni_native_data *nat = getNative(e, o);
- if (technologies_mask == 0 && nat)
+ if (technologies_mask == -1 && nat)
tech_mask = (tNFA_TECHNOLOGY_MASK)nat->tech_mask;
- else if (technologies_mask != 0)
+ else if (technologies_mask != -1)
tech_mask = (tNFA_TECHNOLOGY_MASK) technologies_mask;
-
ALOGD ("%s: enter; tech_mask = %02x", __FUNCTION__, tech_mask);
- if (sDiscoveryEnabled)
+ if (sDiscoveryEnabled && !restart)
{
- ALOGE ("%s: already polling", __FUNCTION__);
+ ALOGE ("%s: already discovering", __FUNCTION__);
return;
}
tNFA_STATUS stat = NFA_STATUS_OK;
- ALOGD ("%s: sIsSecElemSelected=%u", __FUNCTION__, sIsSecElemSelected);
-
PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
if (sRfEnabled) {
@@ -925,34 +925,56 @@ static void nfcManager_enableDiscovery (JNIEnv* e, jobject o, jint technologies_
startRfDiscovery(false);
}
-
- enableDisableLptd(enable_lptd);
-
+ // Check polling configuration
+ if (tech_mask != 0)
{
- SyncEventGuard guard (sNfaEnableDisablePollingEvent);
- stat = NFA_EnablePolling (tech_mask);
- if (stat == NFA_STATUS_OK)
- {
- ALOGD ("%s: wait for enable event", __FUNCTION__);
- sDiscoveryEnabled = true;
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
- ALOGD ("%s: got enabled event", __FUNCTION__);
- }
- else
+ stopPolling_rfDiscoveryDisabled();
+ enableDisableLptd(enable_lptd);
+ startPolling_rfDiscoveryDisabled(tech_mask);
+
+ // Start P2P listening if tag polling was enabled
+ if (sPollingEnabled)
{
- ALOGE ("%s: fail enable discovery; error=0x%X", __FUNCTION__, stat);
+ ALOGD ("%s: Enable p2pListening", __FUNCTION__);
+ PeerToPeer::getInstance().enableP2pListening (!reader_mode);
+
+ if (reader_mode && !sReaderModeEnabled)
+ {
+ sReaderModeEnabled = true;
+ NFA_PauseP2p();
+ NFA_DisableListening();
+ NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION);
+ }
+ else if (sReaderModeEnabled)
+ {
+ struct nfc_jni_native_data *nat = getNative(e, o);
+ sReaderModeEnabled = false;
+ NFA_ResumeP2p();
+ NFA_EnableListening();
+ NFA_SetRfDiscoveryDuration(nat->discovery_duration);
+ }
}
}
-
- // Start P2P listening if tag polling was enabled or the mask was 0.
- if (sDiscoveryEnabled || (tech_mask == 0))
+ else
{
- ALOGD ("%s: Enable p2pListening", __FUNCTION__);
- PeerToPeer::getInstance().enableP2pListening (true);
+ // No technologies configured, stop polling
+ stopPolling_rfDiscoveryDisabled();
}
+ // Check listen configuration
+ if (enable_host_routing)
+ {
+ RoutingManager::getInstance().enableRoutingToHost();
+ RoutingManager::getInstance().commitRouting();
+ }
+ else
+ {
+ RoutingManager::getInstance().disableRoutingToHost();
+ RoutingManager::getInstance().commitRouting();
+ }
// Actually start discovery.
startRfDiscovery (true);
+ sDiscoveryEnabled = true;
PowerSwitch::getInstance ().setModeOn (PowerSwitch::DISCOVERY);
@@ -971,7 +993,7 @@ static void nfcManager_enableDiscovery (JNIEnv* e, jobject o, jint technologies_
** Returns: None
**
*******************************************************************************/
-void nfcManager_disableDiscovery (JNIEnv*, jobject)
+void nfcManager_disableDiscovery (JNIEnv* e, jobject o)
{
tNFA_STATUS status = NFA_STATUS_OK;
ALOGD ("%s: enter;", __FUNCTION__);
@@ -986,21 +1008,12 @@ void nfcManager_disableDiscovery (JNIEnv*, jobject)
// Stop RF Discovery.
startRfDiscovery (false);
- if (sDiscoveryEnabled)
- {
- SyncEventGuard guard (sNfaEnableDisablePollingEvent);
- status = NFA_DisablePolling ();
- if (status == NFA_STATUS_OK)
- {
- sDiscoveryEnabled = false;
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
- }
- else
- ALOGE ("%s: Failed to disable polling; error=0x%X", __FUNCTION__, status);
- }
+ if (sPollingEnabled)
+ status = stopPolling_rfDiscoveryDisabled();
PeerToPeer::getInstance().enableP2pListening (false);
+ sDiscoveryEnabled = false;
//if nothing is active after this, then tell the controller to power down
if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::DISCOVERY))
PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
@@ -1188,8 +1201,8 @@ static jboolean nfcManager_doDeinitialize (JNIEnv*, jobject)
nativeLlcpConnectionlessSocket_abortWait();
sIsNfaEnabled = false;
sDiscoveryEnabled = false;
+ sPollingEnabled = false;
sIsDisabling = false;
- sIsSecElemSelected = false;
gActivated = false;
{
@@ -1287,70 +1300,6 @@ static jobject nfcManager_doCreateLlcpConnectionlessSocket (JNIEnv *, jobject, j
return NULL;
}
-
-/*******************************************************************************
-**
-** Function: nfcManager_enableRoutingToHost
-**
-** Description: NFC controller starts routing data to host.
-** e: JVM environment.
-** o: Java object.
-**
-** Returns: None
-**
-*******************************************************************************/
-static void nfcManager_enableRoutingToHost(JNIEnv*, jobject)
-{
- ALOGD ("%s: enter", __FUNCTION__);
- PowerSwitch::getInstance ().setLevel (PowerSwitch::FULL_POWER);
- PowerSwitch::getInstance ().setModeOn (PowerSwitch::HOST_ROUTING);
- if (sRfEnabled) {
- // Stop RF discovery to reconfigure
- startRfDiscovery(false);
- }
- RoutingManager::getInstance().commitRouting();
- startRfDiscovery(true);
- ALOGD ("%s: exit", __FUNCTION__);
-}
-
-/*******************************************************************************
-**
-** Function: nfcManager_disableRoutingToHost
-**
-** Description: NFC controller stops routing data to host.
-** e: JVM environment.
-** o: Java object.
-**
-** Returns: None
-**
-*******************************************************************************/
-static void nfcManager_disableRoutingToHost(JNIEnv*, jobject)
-{
- ALOGD ("%s: enter", __FUNCTION__);
- bool rfWasEnabled = false;
-
- if (PowerSwitch::getInstance ().getLevel() == PowerSwitch::LOW_POWER)
- {
- ALOGD ("%s: no need to disable routing while power is OFF", __FUNCTION__);
- goto TheEnd;
- }
-
- if (sRfEnabled) {
- rfWasEnabled = true;
- // Stop RF discovery to reconfigure
- startRfDiscovery(false);
- }
- RoutingManager::getInstance().commitRouting();
- if (rfWasEnabled)
- {
- startRfDiscovery(true);
- }
- if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::HOST_ROUTING))
- PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER);
-TheEnd:
- ALOGD ("%s: exit", __FUNCTION__);
-}
-
/*******************************************************************************
**
** Function: isPeerToPeer
@@ -1593,47 +1542,6 @@ static void nfcManager_doSetP2pTargetModes (JNIEnv*, jobject, jint modes)
PeerToPeer::getInstance().setP2pListenMask(mask);
}
-static void nfcManager_doEnableReaderMode (JNIEnv*, jobject, jint technologies)
-{
- if (sDiscoveryEnabled) {
- sReaderModeEnabled = true;
- PeerToPeer::getInstance().enableP2pListening(false);
- NFA_PauseP2p();
- NFA_DisableListening();
- // Limit polling to these technologies
- int tech_mask = 0;
- if (technologies & 0x01)
- tech_mask |= NFA_TECHNOLOGY_MASK_A;
- if (technologies & 0x02)
- tech_mask |= NFA_TECHNOLOGY_MASK_B;
- if (technologies & 0x04)
- tech_mask |= NFA_TECHNOLOGY_MASK_F;
- if (technologies & 0x08)
- tech_mask |= NFA_TECHNOLOGY_MASK_ISO15693;
- if (technologies & 0x10)
- tech_mask |= NFA_TECHNOLOGY_MASK_KOVIO;
-
- enableDisableLptd(false);
- NFA_SetRfDiscoveryDuration(READER_MODE_DISCOVERY_DURATION);
- restartPollingWithTechMask(tech_mask);
- }
-}
-
-static void nfcManager_doDisableReaderMode (JNIEnv* e, jobject o)
-{
- struct nfc_jni_native_data *nat = getNative(e, o);
- if (sDiscoveryEnabled) {
- sReaderModeEnabled = false;
- NFA_ResumeP2p();
- PeerToPeer::getInstance().enableP2pListening(true);
- NFA_EnableListening();
-
- enableDisableLptd(true);
- NFA_SetRfDiscoveryDuration(nat->discovery_duration);
- restartPollingWithTechMask(nat->tech_mask);
- }
-}
-
static void nfcManager_doEnableScreenOffSuspend(JNIEnv* e, jobject o)
{
PowerSwitch::getInstance().setScreenOffPowerState(PowerSwitch::POWER_STATE_FULL);
@@ -1672,15 +1580,9 @@ static JNINativeMethod gMethods[] =
{"unrouteAid", "([B)Z",
(void*) nfcManager_unrouteAid},
- {"enableDiscovery", "(IZ)V",
+ {"doEnableDiscovery", "(IZZZZ)V",
(void*) nfcManager_enableDiscovery},
- {"enableRoutingToHost", "()V",
- (void*) nfcManager_enableRoutingToHost},
-
- {"disableRoutingToHost", "()V",
- (void*) nfcManager_disableRoutingToHost},
-
{"doCheckLlcp", "()Z",
(void *)nfcManager_doCheckLlcp},
@@ -1720,12 +1622,6 @@ static JNINativeMethod gMethods[] =
{"doSetP2pTargetModes", "(I)V",
(void *)nfcManager_doSetP2pTargetModes},
- {"doEnableReaderMode", "(I)V",
- (void *)nfcManager_doEnableReaderMode},
-
- {"doDisableReaderMode", "()V",
- (void *)nfcManager_doDisableReaderMode},
-
{"doEnableScreenOffSuspend", "()V",
(void *)nfcManager_doEnableScreenOffSuspend},
@@ -1846,36 +1742,6 @@ bool nfcManager_isNfcActive()
return sIsNfaEnabled;
}
-void restartPollingWithTechMask (int tech_mask)
-{
- tNFA_STATUS stat = NFA_STATUS_FAILED;
- startRfDiscovery (false);
- {
- SyncEventGuard guard (sNfaEnableDisablePollingEvent);
- stat = NFA_DisablePolling ();
- if (stat == NFA_STATUS_OK)
- {
- ALOGD ("%s: wait for enable event", __FUNCTION__);
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
- }
- else
- {
- ALOGE ("%s: failed to disable polling; error=0x%X", __FUNCTION__, stat);
- goto TheEnd;
- }
- stat = NFA_EnablePolling (tech_mask);
- if (stat == NFA_STATUS_OK)
- {
- ALOGD ("%s: wait for enable event", __FUNCTION__);
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
- }
- else
- ALOGE ("%s: fail enable polling; error=0x%X", __FUNCTION__, stat);
- }
-TheEnd:
- startRfDiscovery(true);
-}
-
/*******************************************************************************
**
** Function: startStopPolling
@@ -1889,41 +1755,56 @@ TheEnd:
void startStopPolling (bool isStartPolling)
{
ALOGD ("%s: enter; isStart=%u", __FUNCTION__, isStartPolling);
+ startRfDiscovery (false);
+
+ if (isStartPolling) startPolling_rfDiscoveryDisabled(0);
+ else stopPolling_rfDiscoveryDisabled();
+
+ startRfDiscovery (true);
+ ALOGD ("%s: exit", __FUNCTION__);
+}
+
+
+static tNFA_STATUS startPolling_rfDiscoveryDisabled(tNFA_TECHNOLOGY_MASK tech_mask) {
tNFA_STATUS stat = NFA_STATUS_FAILED;
- startRfDiscovery (false);
- if (isStartPolling)
- {
- tNFA_TECHNOLOGY_MASK tech_mask = DEFAULT_TECH_MASK;
- unsigned long num = 0;
- if (GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num)))
- tech_mask = num;
+ unsigned long num = 0;
- SyncEventGuard guard (sNfaEnableDisablePollingEvent);
- ALOGD ("%s: enable polling", __FUNCTION__);
- stat = NFA_EnablePolling (tech_mask);
- if (stat == NFA_STATUS_OK)
- {
- ALOGD ("%s: wait for enable event", __FUNCTION__);
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
- }
- else
- ALOGE ("%s: fail enable polling; error=0x%X", __FUNCTION__, stat);
+ if (tech_mask == 0 && GetNumValue(NAME_POLLING_TECH_MASK, &num, sizeof(num)))
+ tech_mask = num;
+ else if (tech_mask == 0) tech_mask = DEFAULT_TECH_MASK;
+
+ SyncEventGuard guard (sNfaEnableDisablePollingEvent);
+ ALOGD ("%s: enable polling", __FUNCTION__);
+ stat = NFA_EnablePolling (tech_mask);
+ if (stat == NFA_STATUS_OK)
+ {
+ ALOGD ("%s: wait for enable event", __FUNCTION__);
+ sPollingEnabled = true;
+ sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_ENABLED_EVT
}
else
{
- SyncEventGuard guard (sNfaEnableDisablePollingEvent);
- ALOGD ("%s: disable polling", __FUNCTION__);
- stat = NFA_DisablePolling ();
- if (stat == NFA_STATUS_OK)
- {
- sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
- }
- else
- ALOGE ("%s: fail disable polling; error=0x%X", __FUNCTION__, stat);
+ ALOGE ("%s: fail enable polling; error=0x%X", __FUNCTION__, stat);
}
- startRfDiscovery (true);
- ALOGD ("%s: exit", __FUNCTION__);
+
+ return stat;
+}
+
+static tNFA_STATUS stopPolling_rfDiscoveryDisabled() {
+ tNFA_STATUS stat = NFA_STATUS_FAILED;
+
+ SyncEventGuard guard (sNfaEnableDisablePollingEvent);
+ ALOGD ("%s: disable polling", __FUNCTION__);
+ stat = NFA_DisablePolling ();
+ if (stat == NFA_STATUS_OK) {
+ sPollingEnabled = false;
+ sNfaEnableDisablePollingEvent.wait (); //wait for NFA_POLL_DISABLED_EVT
+ } else {
+ ALOGE ("%s: fail disable polling; error=0x%X", __FUNCTION__, stat);
+ }
+
+ return stat;
}
diff --git a/nci/jni/RoutingManager.cpp b/nci/jni/RoutingManager.cpp
index 0a7fe5c0..71ab47dc 100644
--- a/nci/jni/RoutingManager.cpp
+++ b/nci/jni/RoutingManager.cpp
@@ -65,8 +65,17 @@ bool RoutingManager::initialize (nfc_jni_native_data* native)
mDefaultEe = 0x00;
ALOGD("%s: default route is 0x%02X", fn, mDefaultEe);
- setDefaultRouting();
mRxDataBuffer.clear ();
+
+ // Tell the host-routing to only listen on Nfc-A
+ nfaStat = NFA_CeSetIsoDepListenTech(0x01);
+ if (nfaStat != NFA_STATUS_OK)
+ ALOGE ("Failed to configure CE IsoDep technologies");
+
+ // Register a wild-card for AIDs routed to the host
+ nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
+ if (nfaStat != NFA_STATUS_OK)
+ ALOGE("Failed to register wildcard AID for DH");
return true;
}
@@ -76,49 +85,47 @@ RoutingManager& RoutingManager::getInstance ()
return manager;
}
-void RoutingManager::setDefaultRouting()
+void RoutingManager::enableRoutingToHost()
{
tNFA_STATUS nfaStat;
- SyncEventGuard guard (mRoutingEvent);
- // Default routing for NFC-A technology
- nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0x01, 0, 0);
- if (nfaStat == NFA_STATUS_OK)
- mRoutingEvent.wait ();
- else
- ALOGE ("Fail to set default tech routing");
- // Default routing for IsoDep protocol
- nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0);
- if (nfaStat == NFA_STATUS_OK)
- mRoutingEvent.wait ();
- else
- ALOGE ("Fail to set default proto routing");
-
- // Tell the UICC to only listen on Nfc-A
- nfaStat = NFA_CeConfigureUiccListenTech (mDefaultEe, 0x01);
- if (nfaStat != NFA_STATUS_OK)
- ALOGE ("Failed to configure UICC listen technologies");
+ {
+ SyncEventGuard guard (mRoutingEvent);
+ // Default routing for NFC-A technology
+ nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0x01, 0, 0);
+ if (nfaStat == NFA_STATUS_OK)
+ mRoutingEvent.wait ();
+ else
+ ALOGE ("Fail to set default tech routing");
- // Tell the host-routing to only listen on Nfc-A
- nfaStat = NFA_CeSetIsoDepListenTech(0x01);
- if (nfaStat != NFA_STATUS_OK)
- ALOGE ("Failed to configure CE IsoDep technologies");
+ // Default routing for IsoDep protocol
+ nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0);
+ if (nfaStat == NFA_STATUS_OK)
+ mRoutingEvent.wait ();
+ else
+ ALOGE ("Fail to set default proto routing");
+ }
+}
- // Register a wild-card for AIDs routed to the host
- nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
- if (nfaStat != NFA_STATUS_OK)
- ALOGE("Failed to register wildcard AID for DH");
+void RoutingManager::disableRoutingToHost()
+{
+ tNFA_STATUS nfaStat;
{
- SyncEventGuard guard (mEeUpdateEvent);
- // Commit the routing configuration
- nfaStat = NFA_EeUpdateNow();
+ SyncEventGuard guard (mRoutingEvent);
+ // Default routing for NFC-A technology
+ nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0);
if (nfaStat == NFA_STATUS_OK)
- {
- mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT
- }
+ mRoutingEvent.wait ();
+ else
+ ALOGE ("Fail to set default tech routing");
+
+ // Default routing for IsoDep protocol
+ nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0);
+ if (nfaStat == NFA_STATUS_OK)
+ mRoutingEvent.wait ();
else
- ALOGE("Failed to commit routing configuration");
+ ALOGE ("Fail to set default proto routing");
}
}
diff --git a/nci/jni/RoutingManager.h b/nci/jni/RoutingManager.h
index ea3a840b..729dfe99 100644
--- a/nci/jni/RoutingManager.h
+++ b/nci/jni/RoutingManager.h
@@ -36,6 +36,8 @@ public:
static RoutingManager& getInstance ();
bool initialize(nfc_jni_native_data* native);
+ void enableRoutingToHost();
+ void disableRoutingToHost();
bool addAidRouting(const UINT8* aid, UINT8 aidLen, int route);
bool removeAidRouting(const UINT8* aid, UINT8 aidLen);
bool commitRouting();
@@ -45,7 +47,6 @@ private:
RoutingManager(const RoutingManager&);
RoutingManager& operator=(const RoutingManager&);
- void setDefaultRouting();
void handleData (const UINT8* data, UINT32 dataLen, tNFA_STATUS status);
void notifyActivated ();
void notifyDeactivated ();
diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
index 4e98a74d..87489e6f 100755
--- a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
+++ b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
@@ -24,6 +24,7 @@ import android.util.Log;
import com.android.nfc.DeviceHost;
import com.android.nfc.LlcpException;
+import com.android.nfc.NfcDiscoveryParameters;
/**
* Native interface to the NFC Manager functions
@@ -94,17 +95,20 @@ public class NativeNfcManager implements DeviceHost {
@Override
public native boolean unrouteAid(byte[] aid);
- @Override
- public native void enableDiscovery(int techMask, boolean enableLowPowerDiscovery);
+ private native void doEnableDiscovery(int techMask,
+ boolean enableLowPowerPolling,
+ boolean enableReaderMode,
+ boolean enableHostRouting,
+ boolean restart);
@Override
- public native void disableDiscovery();
-
- @Override
- public native void enableRoutingToHost();
+ public void enableDiscovery(NfcDiscoveryParameters params, boolean restart) {
+ doEnableDiscovery(params.getTechMask(), params.shouldEnableLowPowerDiscovery(),
+ params.shouldEnableReaderMode(), params.shouldEnableHostRouting(), restart);
+ }
@Override
- public native void disableRoutingToHost();
+ public native void disableDiscovery();
private native NativeLlcpConnectionlessSocket doCreateLlcpConnectionlessSocket(int nSap,
String sn);
@@ -261,11 +265,6 @@ public class NativeNfcManager implements DeviceHost {
}
@Override
- public boolean enablePN544Quirks() {
- return false;
- }
-
- @Override
public int getDefaultLlcpMiu() {
return DEFAULT_LLCP_MIU;
}
@@ -281,20 +280,6 @@ public class NativeNfcManager implements DeviceHost {
return doDump();
}
- private native void doEnableReaderMode(int technologies);
- @Override
- public boolean enableReaderMode(int technologies) {
- doEnableReaderMode(technologies);
- return true;
- }
-
- private native void doDisableReaderMode();
- @Override
- public boolean disableReaderMode() {
- doDisableReaderMode();
- return true;
- }
-
private native void doEnableScreenOffSuspend();
@Override
public boolean enableScreenOffSuspend() {
diff --git a/nxp/jni/com_android_nfc_NativeNfcManager.cpp b/nxp/jni/com_android_nfc_NativeNfcManager.cpp
index 27061c57..489a615b 100644
--- a/nxp/jni/com_android_nfc_NativeNfcManager.cpp
+++ b/nxp/jni/com_android_nfc_NativeNfcManager.cpp
@@ -1356,7 +1356,7 @@ static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o)
// TODO: use enable_lptd
static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jint modes,
- jboolean enable_lptd)
+ jboolean, jboolean reader_mode, jboolean restart)
{
NFCSTATUS ret;
struct nfc_jni_native_data *nat;
@@ -1387,17 +1387,30 @@ static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jin
nat->registry_info.NFC==TRUE?"P2P":"",
nat->registry_info.ISO15693==TRUE?"R":"", ret);
+ if (modes != 0)
+ {
+ if (reader_mode)
+ {
+ nat->p2p_initiator_modes = 0;
+ nat->p2p_target_modes = 0;
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
+ nat->discovery_cfg.Duration = 200000; /* in ms */
+ }
+ else
+ {
+ nat->p2p_initiator_modes = phNfc_eP2P_ALL;
+ nat->p2p_target_modes = 0x0E; // All passive except 106, active
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
+ nat->discovery_cfg.Duration = 300000; /* in ms */
+ }
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
+ nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
+ }
- if (modes != 0)
- {
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
- }
-
- nfc_jni_start_discovery_locked(nat, false);
+ nfc_jni_start_discovery_locked(nat, restart);
clean_and_return:
CONCURRENCY_UNLOCK();
}
@@ -2196,43 +2209,6 @@ static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject)
emergency_recovery(NULL);
}
-static void com_android_nfc_NfcManager_doEnableReaderMode(JNIEnv *e, jobject o,
- jint modes)
-{
- struct nfc_jni_native_data *nat = NULL;
- nat = nfc_jni_get_nat(e, o);
- CONCURRENCY_LOCK();
- nat->p2p_initiator_modes = 0;
- nat->p2p_target_modes = 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
- nat->discovery_cfg.Duration = 200000; /* in ms */
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
- nfc_jni_start_discovery_locked(nat, FALSE);
- CONCURRENCY_UNLOCK();
-}
-
-static void com_android_nfc_NfcManager_doDisableReaderMode(JNIEnv *e, jobject o)
-{
- struct nfc_jni_native_data *nat = NULL;
- nat = nfc_jni_get_nat(e, o);
- CONCURRENCY_LOCK();
- nat->p2p_initiator_modes = phNfc_eP2P_ALL;
- nat->p2p_target_modes = 0x0E; // All passive except 106, active
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
- nat->discovery_cfg.Duration = 300000; /* in ms */
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
- nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
- nfc_jni_start_discovery_locked(nat, FALSE);
- CONCURRENCY_UNLOCK();
-}
-
static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
jint modes)
{
@@ -2383,7 +2359,7 @@ static JNINativeMethod gMethods[] =
{"doDeinitialize", "()Z",
(void *)com_android_nfc_NfcManager_deinitialize},
- {"enableDiscovery", "(IZ)V",
+ {"doEnableDiscovery", "(IZZZ)V",
(void *)com_android_nfc_NfcManager_enableDiscovery},
{"doCheckLlcp", "()Z",
@@ -2425,12 +2401,6 @@ static JNINativeMethod gMethods[] =
{"doSetP2pTargetModes","(I)V",
(void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
- {"doEnableReaderMode","(I)V",
- (void *)com_android_nfc_NfcManager_doEnableReaderMode},
-
- {"doDisableReaderMode","()V",
- (void *)com_android_nfc_NfcManager_doDisableReaderMode},
-
{"doDump", "()Ljava/lang/String;",
(void *)com_android_nfc_NfcManager_doDump},
};
diff --git a/nxp/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nxp/src/com/android/nfc/dhimpl/NativeNfcManager.java
index a69e3b53..9d2ebeae 100755
--- a/nxp/src/com/android/nfc/dhimpl/NativeNfcManager.java
+++ b/nxp/src/com/android/nfc/dhimpl/NativeNfcManager.java
@@ -27,6 +27,7 @@ import android.nfc.ErrorCodes;
import android.nfc.tech.Ndef;
import android.nfc.tech.TagTechnology;
import android.util.Log;
+import com.android.nfc.NfcDiscoveryParameters;
import java.io.File;
@@ -151,23 +152,18 @@ public class NativeNfcManager implements DeviceHost {
return false;
}
+ private native void doEnableDiscovery(int techMask,
+ boolean enableLowPowerPolling,
+ boolean enableReaderMode,
+ boolean restart);
@Override
- public native void enableDiscovery(int techMask, boolean enableLowPowerDiscovery);
-
- @Override
- public native void disableDiscovery();
-
- @Override
- public void enableRoutingToHost()
- {
-
+ public void enableDiscovery(NfcDiscoveryParameters params, boolean restart) {
+ doEnableDiscovery(params.getTechMask(), params.shouldEnableLowPowerDiscovery(),
+ params.shouldEnableReaderMode(), restart);
}
@Override
- public void disableRoutingToHost()
- {
-
- }
+ public native void disableDiscovery();
private native NativeLlcpConnectionlessSocket doCreateLlcpConnectionlessSocket(int nSap,
String sn);
@@ -315,18 +311,6 @@ public class NativeNfcManager implements DeviceHost {
doSetP2pTargetModes(modes);
}
- private native void doEnableReaderMode(int technologies);
- public boolean enableReaderMode(int technologies) {
- doEnableReaderMode(technologies);
- return true;
- }
-
- private native void doDisableReaderMode();
- public boolean disableReaderMode() {
- doDisableReaderMode();
- return true;
- }
-
@Override
public boolean enableScreenOffSuspend() {
// Snooze mode not supported on NXP silicon
@@ -348,11 +332,6 @@ public class NativeNfcManager implements DeviceHost {
}
@Override
- public boolean enablePN544Quirks() {
- return true;
- }
-
- @Override
public int getDefaultLlcpMiu() {
return DEFAULT_LLCP_MIU;
}
diff --git a/src/com/android/nfc/DeviceHost.java b/src/com/android/nfc/DeviceHost.java
index 9c4beb44..a1e7b052 100644
--- a/src/com/android/nfc/DeviceHost.java
+++ b/src/com/android/nfc/DeviceHost.java
@@ -171,14 +171,10 @@ public interface DeviceHost {
public String getName();
- public void enableDiscovery(int techMask, boolean enableLowPowerDiscovery);
+ public void enableDiscovery(NfcDiscoveryParameters params, boolean restart);
public void disableDiscovery();
- public void enableRoutingToHost();
-
- public void disableRoutingToHost();
-
public boolean sendRawFrame(byte[] data);
public boolean routeAid(byte[] aid, int route);
@@ -216,18 +212,12 @@ public interface DeviceHost {
boolean getExtendedLengthApdusSupported();
- boolean enablePN544Quirks();
-
int getDefaultLlcpMiu();
int getDefaultLlcpRwSize();
String dump();
- boolean enableReaderMode(int technologies);
-
- boolean disableReaderMode();
-
boolean enableScreenOffSuspend();
boolean disableScreenOffSuspend();
diff --git a/src/com/android/nfc/NfcDiscoveryParameters.java b/src/com/android/nfc/NfcDiscoveryParameters.java
new file mode 100644
index 00000000..121e986c
--- /dev/null
+++ b/src/com/android/nfc/NfcDiscoveryParameters.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.nfc;
+
+/**
+ * Parameters for enabling NFC tag discovery and polling,
+ * and host card emulation.
+ */
+public final class NfcDiscoveryParameters {
+
+ public static class Builder {
+
+ private NfcDiscoveryParameters mParameters;
+
+ private Builder() {
+ mParameters = new NfcDiscoveryParameters();
+ }
+
+ public NfcDiscoveryParameters.Builder setTechMask(int techMask) {
+ mParameters.mTechMask = techMask;
+ return this;
+ }
+
+ public NfcDiscoveryParameters.Builder setEnableLowPowerDiscovery(boolean enable) {
+ mParameters.mEnableLowPowerDiscovery = enable;
+ return this;
+ }
+
+ public NfcDiscoveryParameters.Builder setEnableReaderMode(boolean enable) {
+ mParameters.mEnableReaderMode = enable;
+
+ if (enable) {
+ mParameters.mEnableLowPowerDiscovery = false;
+ }
+
+ return this;
+ }
+
+ public NfcDiscoveryParameters.Builder setEnableHostRouting(boolean enable) {
+ mParameters.mEnableHostRouting = enable;
+ return this;
+ }
+
+ public NfcDiscoveryParameters build() {
+ if (mParameters.mEnableReaderMode && mParameters.mEnableLowPowerDiscovery) {
+ throw new IllegalStateException("Can't enable LPTD and reader mode simultaneously");
+ }
+ return mParameters;
+ }
+ }
+
+ // Polling technology masks
+ static final int NFC_POLL_DEFAULT = -1;
+ static final int NFC_POLL_A = 0x01;
+ static final int NFC_POLL_B = 0x02;
+ static final int NFC_POLL_F = 0x04;
+ static final int NFC_POLL_ISO15693 = 0x08;
+ static final int NFC_POLL_B_PRIME = 0x10;
+ static final int NFC_POLL_KOVIO = 0x20;
+
+ private int mTechMask = 0;
+ private boolean mEnableLowPowerDiscovery = true;
+ private boolean mEnableReaderMode = false;
+ private boolean mEnableHostRouting = false;
+
+ public NfcDiscoveryParameters() {}
+
+ public int getTechMask() {
+ return mTechMask;
+ }
+
+ public boolean shouldEnableLowPowerDiscovery() {
+ return mEnableLowPowerDiscovery;
+ }
+
+ public boolean shouldEnableReaderMode() {
+ return mEnableReaderMode;
+ }
+
+ public boolean shouldEnableHostRouting() {
+ return mEnableHostRouting;
+ }
+
+ public boolean shouldEnableDiscovery() {
+ return mTechMask != 0 || mEnableHostRouting;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if ((obj == null) || (obj.getClass() != this.getClass())) {
+ return false;
+ }
+ NfcDiscoveryParameters params = (NfcDiscoveryParameters) obj;
+ return mTechMask == params.mTechMask &&
+ (mEnableLowPowerDiscovery == params.mEnableLowPowerDiscovery) &&
+ (mEnableReaderMode == params.mEnableReaderMode) &&
+ (mEnableHostRouting == params.mEnableHostRouting);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ if (mTechMask == NFC_POLL_DEFAULT) {
+ sb.append("mTechMask: default\n");
+ } else {
+ sb.append("mTechMask: " + Integer.toString(mTechMask) + "\n");
+ }
+ sb.append("mEnableLPD: " + Boolean.toString(mEnableLowPowerDiscovery) + "\n");
+ sb.append("mEnableReader: " + Boolean.toString(mEnableReaderMode) + "\n");
+ sb.append("mEnableHostRouting: " + Boolean.toString(mEnableHostRouting));
+ return sb.toString();
+ }
+
+ public static NfcDiscoveryParameters.Builder newBuilder() {
+ return new Builder();
+ }
+
+ public static NfcDiscoveryParameters getDefaultInstance() {
+ return new NfcDiscoveryParameters();
+ }
+}
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index f0bb2c76..456a2b9c 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -27,7 +27,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources.NotFoundException;
import android.media.AudioManager;
@@ -112,7 +111,6 @@ public class NfcService implements DeviceHostListener {
static final int TASK_BOOT = 3;
// Polling technology masks
- static final int NFC_POLL_DEFAULT = 0;
static final int NFC_POLL_A = 0x01;
static final int NFC_POLL_B = 0x02;
static final int NFC_POLL_F = 0x04;
@@ -120,6 +118,9 @@ public class NfcService implements DeviceHostListener {
static final int NFC_POLL_B_PRIME = 0x10;
static final int NFC_POLL_KOVIO = 0x20;
+ // minimum screen state that enables NFC polling
+ static final int NFC_POLLING_MODE = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
+
// Time to wait for NFC controller to initialize before watchdog
// goes off. This time is chosen large, because firmware download
// may be a part of initialization.
@@ -148,11 +149,7 @@ public class NfcService implements DeviceHostListener {
private final ReaderModeDeathRecipient mReaderModeDeathRecipient =
new ReaderModeDeathRecipient();
- // fields below must be used only on the UI thread and therefore aren't synchronized
- boolean mP2pStarted = false;
-
- // minimum screen state that enables NFC polling (discovery)
- private int mPollingMode = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
+ private boolean mDiscoveryEnabled = false;
private int mLockscreenPollMask;
private boolean mLockscreenDispatchEnabled;
@@ -161,14 +158,10 @@ public class NfcService implements DeviceHostListener {
int mScreenState;
boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning
boolean mIsNdefPushEnabled;
- boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling
- boolean mHostRouteEnabled; // current Device Host state of host-based routing
- boolean mReaderModeEnabled; // current Device Host state of reader mode
+ NfcDiscoveryParameters mCurrentDiscoveryParameters;
ReaderModeParams mReaderModeParams;
- List<PackageInfo> mInstalledPackages; // cached version of installed packages
-
// mState is protected by this, however it is only modified in onCreate()
// and the default AsyncTask thread so it is read unprotected from that
// thread
@@ -203,7 +196,6 @@ public class NfcService implements DeviceHostListener {
private int mUserId;
private static NfcService sService;
- private int mCurrentTechMask;
public static NfcService getInstance() {
return sService;
@@ -373,14 +365,6 @@ public class NfcService implements DeviceHostListener {
}
}
- void updatePackageCache() {
- PackageManager pm = mContext.getPackageManager();
- List<PackageInfo> packages = pm.getInstalledPackages(0, UserHandle.USER_OWNER);
- synchronized (this) {
- mInstalledPackages = packages;
- }
- }
-
/**
* Manages tasks that involve turning on/off the NFC controller.
* <p/>
@@ -777,10 +761,9 @@ public class NfcService implements DeviceHostListener {
@Override
public void setP2pModes(int initiatorModes, int targetModes) throws RemoteException {
NfcPermissions.enforceAdminPermissions(mContext);
-
mDeviceHost.setP2pInitiatorModes(initiatorModes);
mDeviceHost.setP2pTargetModes(targetModes);
- reenableDiscovery(NFC_POLL_DEFAULT, false);
+ applyRouting(true);
}
@Override
@@ -828,7 +811,6 @@ public class NfcService implements DeviceHostListener {
boolean enableLockscreenDispatch = lockscreenDispatch != null;
int lockscreenPollMask;
- int pollingMode;
if (enableLockscreenDispatch) {
lockscreenPollMask = computeLockscreenPollMask(techList);
@@ -838,18 +820,13 @@ public class NfcService implements DeviceHostListener {
mDeviceHost.disableScreenOffSuspend();
}
- pollingMode = enableLockscreenDispatch
- ? ScreenStateHelper.SCREEN_STATE_ON_LOCKED
- : ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED;
-
synchronized (NfcService.this) {
- mPollingMode = pollingMode;
mLockscreenPollMask = lockscreenPollMask;
mLockscreenDispatchEnabled = enableLockscreenDispatch;
mNfcDispatcher.registerLockscreenDispatch(lockscreenDispatch);
}
- applyRouting(true);
+ applyRouting(false);
}
private int computeLockscreenPollMask(int[] techList) {
@@ -1319,91 +1296,29 @@ public class NfcService implements DeviceHostListener {
mHandoverManager.setEnabled(true);
}
}
+ // Special case: if we're transitioning to unlocked state while
+ // still talking to a tag, postpone re-configuration.
+ if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED && isTagPresent()) {
+ Log.d(TAG, "Not updating discovery parameters, tag connected.");
+ return;
+ }
+
try {
watchDog.start();
-
- if (mDeviceHost.enablePN544Quirks() &&
- mScreenState == ScreenStateHelper.SCREEN_STATE_OFF) {
- /* TODO undo this after the LLCP stack is fixed.
- * Use a different sequence when turning the screen off to
- * workaround race conditions in pn544 libnfc. The race occurs
- * when we change routing while there is a P2P target connect.
- * The async LLCP callback will crash since the routing code
- * is overwriting globals it relies on.
- */
- if (getPollingMode() > ScreenStateHelper.SCREEN_STATE_OFF) {
- if (force || mNfcPollingEnabled) {
- Log.d(TAG, "NFC-C OFF, disconnect");
- mNfcPollingEnabled = false;
- mDeviceHost.disableDiscovery();
- maybeDisconnectTarget();
- }
- }
- return;
- }
-
- if (mIsHceCapable && mScreenState
- >= ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
- if (!mHostRouteEnabled || force) {
- mHostRouteEnabled = true;
- mDeviceHost.enableRoutingToHost();
- }
- } else {
- if (force || mHostRouteEnabled) {
- mHostRouteEnabled = false;
- mDeviceHost.disableRoutingToHost();
- }
- }
-
- // configure NFC-C polling
- if (!mInProvisionMode && mScreenState >= getPollingMode()) {
- if (force || !mNfcPollingEnabled) {
- Log.d(TAG, "NFC-C ON");
-
- if (force && mNfcPollingEnabled) {
- // disable discovery so new tech mask takes effect
- mDeviceHost.disableDiscovery();
- }
-
- if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
- mDeviceHost.enableDiscovery(mLockscreenPollMask, false);
- } else {
- reenableDiscovery(NFC_POLL_DEFAULT, true);
- }
-
- mNfcPollingEnabled = true;
- } else if (mNfcPollingEnabled) {
- if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED
- && (!isTagPresent()) && mCurrentTechMask != NFC_POLL_DEFAULT) {
- reenableDiscovery(NFC_POLL_DEFAULT, true);
- }
- }
- if (mReaderModeParams != null && !mReaderModeEnabled) {
- mReaderModeEnabled = true;
- mDeviceHost.enableReaderMode(mReaderModeParams.flags);
- }
- if (mReaderModeParams == null && mReaderModeEnabled) {
- mReaderModeEnabled = false;
- mDeviceHost.disableReaderMode();
- }
- } else if (mInProvisionMode && mScreenState
- >= ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
- // Special case for setup provisioning
- if (!mNfcPollingEnabled) {
- Log.d(TAG, "NFC-C ON");
- reenableDiscovery(NFC_POLL_DEFAULT, true);
- mNfcPollingEnabled = true;
- }
- } else {
- if (force || mNfcPollingEnabled) {
- Log.d(TAG, "NFC-C OFF");
- if (mReaderModeEnabled) {
- mReaderModeEnabled = false;
- mDeviceHost.disableReaderMode();
- }
- mNfcPollingEnabled = false;
+ // Compute new polling parameters
+ NfcDiscoveryParameters newParams = computeDiscoveryParameters(mScreenState);
+ if (force || !newParams.equals(mCurrentDiscoveryParameters)) {
+ if (newParams.shouldEnableDiscovery()) {
+ boolean shouldRestart = mDiscoveryEnabled;
+ mDeviceHost.enableDiscovery(newParams, shouldRestart);
+ mDiscoveryEnabled = true;
+ } else {
mDeviceHost.disableDiscovery();
+ mDiscoveryEnabled = false;
}
+ mCurrentDiscoveryParameters = newParams;
+ } else {
+ Log.d(TAG, "Discovery configuration equal, not updating.");
}
} finally {
watchDog.cancel();
@@ -1411,14 +1326,44 @@ public class NfcService implements DeviceHostListener {
}
}
- private void reenableDiscovery(int techMask, boolean enableLptd) {
- mCurrentTechMask = techMask;
-
- if (mNfcPollingEnabled) {
- mDeviceHost.disableDiscovery();
+ private NfcDiscoveryParameters computeDiscoveryParameters(int screenState) {
+ // Recompute discovery parameters based on screen state
+ NfcDiscoveryParameters.Builder paramsBuilder = NfcDiscoveryParameters.newBuilder();
+ // Polling
+ if (screenState >= NFC_POLLING_MODE) {
+ // Check if reader-mode is enabled
+ if (mReaderModeParams != null) {
+ int techMask = 0;
+ if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_A) != 0)
+ techMask |= NFC_POLL_A;
+ if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_B) != 0)
+ techMask |= NFC_POLL_B;
+ if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_F) != 0)
+ techMask |= NFC_POLL_F;
+ if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_V) != 0)
+ techMask |= NFC_POLL_ISO15693;
+ if ((mReaderModeParams.flags & NfcAdapter.FLAG_READER_NFC_BARCODE) != 0)
+ techMask |= NFC_POLL_KOVIO;
+
+ paramsBuilder.setTechMask(techMask);
+ paramsBuilder.setEnableReaderMode(true);
+ } else {
+ paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
+ }
+ } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED && mInProvisionMode) {
+ paramsBuilder.setTechMask(NfcDiscoveryParameters.NFC_POLL_DEFAULT);
+ } else if (screenState == ScreenStateHelper.SCREEN_STATE_ON_LOCKED &&
+ mLockscreenDispatchEnabled) {
+ // For lock-screen tags, no low-power polling
+ paramsBuilder.setTechMask(mLockscreenPollMask);
+ paramsBuilder.setEnableLowPowerDiscovery(false);
}
- mDeviceHost.enableDiscovery(techMask, enableLptd);
+ if (mIsHceCapable && mScreenState >= ScreenStateHelper.SCREEN_STATE_ON_LOCKED) {
+ // Host routing is always enabled at lock screen or later
+ paramsBuilder.setEnableHostRouting(true);
+ }
+ return paramsBuilder.build();
}
private boolean isTagPresent() {
@@ -1429,7 +1374,6 @@ public class NfcService implements DeviceHostListener {
}
return false;
}
-
/**
* Disconnect any target if present
*/
@@ -1769,11 +1713,11 @@ public class NfcService implements DeviceHostListener {
// Follow normal dispatch below
}
} catch (RemoteException e) {
- Log.e(TAG, "Reader mode remote has died, falling back.");
+ Log.e(TAG, "Reader mode remote has died, falling back.", e);
// Intentional fall-through
} catch (Exception e) {
// Catch any other exception
- Log.e(TAG, "App exception, not dispatching.");
+ Log.e(TAG, "App exception, not dispatching.", e);
return;
}
}
@@ -1898,9 +1842,9 @@ public class NfcService implements DeviceHostListener {
pw.println("mState=" + stateToString(mState));
pw.println("mIsZeroClickRequested=" + mIsNdefPushEnabled);
pw.println("mScreenState=" + ScreenStateHelper.screenStateToString(mScreenState));
- pw.println("mNfcPollingEnabled=" + mNfcPollingEnabled);
pw.println("mIsAirplaneSensitive=" + mIsAirplaneSensitive);
pw.println("mIsAirplaneToggleable=" + mIsAirplaneToggleable);
+ pw.println(mCurrentDiscoveryParameters);
mP2pLinkManager.dump(fd, pw, args);
if (mIsHceCapable) {
mCardEmulationManager.dump(fd, pw, args);
@@ -1909,8 +1853,4 @@ public class NfcService implements DeviceHostListener {
pw.println(mDeviceHost.dump());
}
}
-
- private synchronized int getPollingMode() {
- return mPollingMode;
- }
}