diff options
author | Martijn Coenen <maco@google.com> | 2013-04-09 10:06:49 -0700 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2013-04-09 12:50:47 -0700 |
commit | b408fc371821c397b47c8722c339c6b4359e062f (patch) | |
tree | fd7115997b14e8e66d27c53dc270472f33d847bd | |
parent | cf4ef456bbf2c10f674b291ef7960af8b6bf6efa (diff) | |
download | android_packages_apps_Nfc-b408fc371821c397b47c8722c339c6b4359e062f.tar.gz android_packages_apps_Nfc-b408fc371821c397b47c8722c339c6b4359e062f.tar.bz2 android_packages_apps_Nfc-b408fc371821c397b47c8722c339c6b4359e062f.zip |
Properly reset field / listen mode flags in SE object.
On NFC disable, the SE object is "finalized" but not
destroyed. It is reused on the next NFC enable, but
the listen mode / field status flags were not cleared
then.
Bug: 8574917
Bug: 8489820
Change-Id: I8e11c60eda47762404a5d5020a0c2e6ff95ead2a
-rwxr-xr-x | nci/jni/NativeNfcManager.cpp | 41 | ||||
-rwxr-xr-x | nci/jni/SecureElement.cpp | 29 | ||||
-rwxr-xr-x | nci/jni/SecureElement.h | 11 | ||||
-rwxr-xr-x | src/com/android/nfc/P2pLinkManager.java | 2 |
4 files changed, 69 insertions, 14 deletions
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp index 90058f91..bf7c7142 100755 --- a/nci/jni/NativeNfcManager.cpp +++ b/nci/jni/NativeNfcManager.cpp @@ -294,7 +294,7 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat case NFA_ACTIVATED_EVT: // NFC link/protocol activated ALOGD("%s: NFA_ACTIVATED_EVT: gIsSelectingRfInterface=%d, sIsDisabling=%d", __FUNCTION__, gIsSelectingRfInterface, sIsDisabling); - if (sIsDisabling) + if (sIsDisabling || !sIsNfaEnabled) break; NfcTag::getInstance().setActivationState (); @@ -360,24 +360,28 @@ static void nfaConnectionCallback (UINT8 connEvent, tNFA_CONN_EVT_DATA* eventDat { if (sSeRfActive) { sSeRfActive = false; - SecureElement::getInstance().notifyListenModeState (false); + if (!sIsDisabling && sIsNfaEnabled) + SecureElement::getInstance().notifyListenModeState (false); } else if (sP2pActive) { sP2pActive = false; // Make sure RF field events are re-enabled - ALOGD("%s: NFA_ACTIVATED_EVT; is p2p", __FUNCTION__); + ALOGD("%s: NFA_DEACTIVATED_EVT; is p2p", __FUNCTION__); // Disable RF field events in case of p2p UINT8 nfa_enable_rf_events[] = { 0x01 }; - ALOGD ("%s: Enabling RF field events", __FUNCTION__); - status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, sizeof(nfa_enable_rf_events), - &nfa_enable_rf_events[0]); - if (status == NFA_STATUS_OK) { - ALOGD ("%s: Enabled RF field events", __FUNCTION__); - } else { - ALOGE ("%s: Failed to enable RF field events", __FUNCTION__); + if (!sIsDisabling && sIsNfaEnabled) + { + ALOGD ("%s: Enabling RF field events", __FUNCTION__); + status = NFA_SetConfig(NCI_PARAM_ID_RF_FIELD_INFO, sizeof(nfa_enable_rf_events), + &nfa_enable_rf_events[0]); + if (status == NFA_STATUS_OK) { + ALOGD ("%s: Enabled RF field events", __FUNCTION__); + } else { + ALOGE ("%s: Failed to enable RF field events", __FUNCTION__); + } + // Consider the field to be off at this point + SecureElement::getInstance().notifyRfFieldEvent (false); } - // Consider the field to be off at this point - SecureElement::getInstance().notifyRfFieldEvent (false); } } @@ -632,9 +636,12 @@ void nfaDeviceManagementCallback (UINT8 dmEvent, tNFA_DM_CBACK_DATA* eventData) case NFA_DM_RF_FIELD_EVT: ALOGD ("%s: NFA_DM_RF_FIELD_EVT; status=0x%X; field status=%u", __FUNCTION__, eventData->rf_field.status, eventData->rf_field.rf_field_status); + if (sIsDisabling || !sIsNfaEnabled) + break; - if (!sIsDisabling && !sP2pActive && eventData->rf_field.status == NFA_STATUS_OK) - SecureElement::getInstance().notifyRfFieldEvent (eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON); + if (!sP2pActive && eventData->rf_field.status == NFA_STATUS_OK) + SecureElement::getInstance().notifyRfFieldEvent ( + eventData->rf_field.rf_field_status == NFA_DM_RF_FIELD_ON); break; case NFA_DM_NFCC_TRANSPORT_ERR_EVT: @@ -919,6 +926,12 @@ void nfcManager_disableDiscovery (JNIEnv*, jobject) if (! PowerSwitch::getInstance ().setModeOff (PowerSwitch::DISCOVERY)) PowerSwitch::getInstance ().setLevel (PowerSwitch::LOW_POWER); + // We may have had RF field notifications that did not cause + // any activate/deactive events. For example, caused by wireless + // charging orbs. Those may cause us to go to sleep while the last + // field event was indicating a field. To prevent sticking in that + // state, always reset the rf field status when we disable discovery. + SecureElement::getInstance().resetRfFieldStatus(); TheEnd: ALOGD ("%s: exit", __FUNCTION__); } diff --git a/nci/jni/SecureElement.cpp b/nci/jni/SecureElement.cpp index 0448b607..101bd38c 100755 --- a/nci/jni/SecureElement.cpp +++ b/nci/jni/SecureElement.cpp @@ -178,6 +178,8 @@ bool SecureElement::initialize (nfc_jni_native_data* native) mbNewEE = true; mNewPipeId = 0; mNewSourceGate = 0; + mRfFieldIsOn = false; + mActivatedInListenMode = false; mCurrentRouteSelection = NoRoute; memset (mEeInfo, 0, sizeof(mEeInfo)); memset (&mUiccInfo, 0, sizeof(mUiccInfo)); @@ -1078,6 +1080,33 @@ void SecureElement::notifyRfFieldEvent (bool isActive) ALOGD ("%s: exit", fn); } +/******************************************************************************* +** +** Function: resetRfFieldStatus +** +** Description: Resets the field status. +** isActive: Whether any secure element is activated. +** +** Returns: None +** +*******************************************************************************/ +void SecureElement::resetRfFieldStatus () +{ + static const char fn [] = "SecureElement::resetRfFieldStatus`"; + ALOGD ("%s: enter;"); + + mMutex.lock(); + mRfFieldIsOn = false; + int ret = clock_gettime (CLOCK_MONOTONIC, &mLastRfFieldToggle); + if (ret == -1) { + ALOGE("%s: clock_gettime failed", fn); + // There is no good choice here... + } + mMutex.unlock(); + + ALOGD ("%s: exit", fn); +} + /******************************************************************************* ** diff --git a/nci/jni/SecureElement.h b/nci/jni/SecureElement.h index 1758590c..c537b2bc 100755 --- a/nci/jni/SecureElement.h +++ b/nci/jni/SecureElement.h @@ -185,6 +185,17 @@ public: /******************************************************************************* ** + ** Function: resetRfFieldStatus (); + ** + ** Description: Resets the field status. + ** + ** Returns: None + ** + *******************************************************************************/ + void resetRfFieldStatus (); + + /******************************************************************************* + ** ** Function: storeUiccInfo ** ** Description: Store a copy of the execution environment information from the stack. diff --git a/src/com/android/nfc/P2pLinkManager.java b/src/com/android/nfc/P2pLinkManager.java index 6c6a1b87..d21ffd5c 100755 --- a/src/com/android/nfc/P2pLinkManager.java +++ b/src/com/android/nfc/P2pLinkManager.java @@ -355,6 +355,8 @@ public class P2pLinkManager implements Handler.Callback, P2pEventListener.Callba break; case LINK_STATE_WAITING_PDU: mLinkState = LINK_STATE_UP; + if (mSendState == SEND_STATE_NOTHING_TO_SEND) + break; if (totalTime < LINK_FIRST_PDU_LIMIT_MS || mSendState == SEND_STATE_SENDING) { connectLlcpServices(); } else { |