diff options
author | Love Khanna <love.khanna@nxp.com> | 2017-05-11 20:31:09 +0530 |
---|---|---|
committer | Ruchi Kandoi <kandoiruchi@google.com> | 2017-07-06 11:49:46 -0700 |
commit | 3a894dda035a331860f0f23e93528527493a07a3 (patch) | |
tree | e5f3247ed588dd3e3f92e983bfb77f120a4fc3fd | |
parent | 195ebc69630febb1901a7ef650d5575e9fc0caaa (diff) | |
download | android_packages_apps_Nfc-3a894dda035a331860f0f23e93528527493a07a3.tar.gz android_packages_apps_Nfc-3a894dda035a331860f0f23e93528527493a07a3.tar.bz2 android_packages_apps_Nfc-3a894dda035a331860f0f23e93528527493a07a3.zip |
NCI2.0 Screen state and power sub state management.
As per NCI2.0 screen state transitions can be
handled without restarting the discovery loop
by using the con_discovery_param.
Also as part of screen trasition power sub state
info is updated to NFCC.
Test: compiles.
Change-Id: I28d7f58b299a8ae9acbe7aa643adfc0a16b787cc
(cherry picked from commit bd4c6c8c4a7553a77da8655c3d4d4816cb577185)
-rwxr-xr-x | nci/jni/NativeNfcManager.cpp | 91 | ||||
-rwxr-xr-x | nci/src/com/android/nfc/dhimpl/NativeNfcManager.java | 6 | ||||
-rw-r--r-- | src/com/android/nfc/DeviceHost.java | 4 | ||||
-rwxr-xr-x | src/com/android/nfc/NfcService.java | 50 | ||||
-rw-r--r-- | src/com/android/nfc/ScreenStateHelper.java | 26 |
5 files changed, 165 insertions, 12 deletions
diff --git a/nci/jni/NativeNfcManager.cpp b/nci/jni/NativeNfcManager.cpp index 282d4459..53d0b4ef 100755 --- a/nci/jni/NativeNfcManager.cpp +++ b/nci/jni/NativeNfcManager.cpp @@ -75,6 +75,7 @@ namespace android *****************************************************************************/ bool gActivated = false; SyncEvent gDeactivatedEvent; +SyncEvent sNfaSetPowerSubState; namespace android { @@ -145,10 +146,12 @@ 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 void nfcManager_doSetScreenState(JNIEnv* e, jobject o, jint screen_state_mask); static uint16_t sCurrentConfigLen; static uint8_t sConfig[256]; - +static int prevScreenState = NFA_SCREEN_STATE_OFF_LOCKED; +static int NFA_SCREEN_POLLING_TAG_MASK = 0x10; ///////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// @@ -749,6 +752,14 @@ void nfaDeviceManagementCallback (uint8_t dmEvent, tNFA_DM_CBACK_DATA* eventData PowerSwitch::getInstance ().deviceManagementCallback (dmEvent, eventData); break; + case NFA_DM_SET_POWER_SUB_STATE_EVT: + { + ALOGD("%s: NFA_DM_SET_POWER_SUB_STATE_EVT; status=0x%X", + __FUNCTION__, eventData->power_sub_state.status); + SyncEventGuard guard (sNfaSetPowerSubState); + sNfaSetPowerSubState.notifyOne(); + } + break; default: ALOGV("%s: unhandled event", __func__); break; @@ -1640,7 +1651,79 @@ static jstring nfcManager_doDump(JNIEnv* e, jobject) return e->NewStringUTF(buffer); } +static jint nfcManager_doGetNciVersion(JNIEnv* , jobject) +{ + return NFC_GetNCIVersion(); +} + +static void nfcManager_doSetScreenState (JNIEnv* e, jobject o, jint screen_state_mask) +{ + tNFA_STATUS status = NFA_STATUS_OK; + uint8_t state = (screen_state_mask & NFA_SCREEN_STATE_MASK); + uint8_t discovry_param = NFA_LISTEN_DH_NFCEE_ENABLE_MASK | NFA_POLLING_DH_ENABLE_MASK; + + ALOGD ("%s: state = %d discovry_param = %d", __FUNCTION__, state, discovry_param); + + if (sIsDisabling || !sIsNfaEnabled ||(NFC_GetNCIVersion() != NCI_VERSION_2_0)) + return; + if (prevScreenState == NFA_SCREEN_STATE_OFF_LOCKED || prevScreenState == NFA_SCREEN_STATE_OFF_UNLOCKED) + { + SyncEventGuard guard (sNfaSetPowerSubState); + status = NFA_SetPowerSubStateForScreenState(state); + if (status != NFA_STATUS_OK) + { + ALOGE ("%s: fail enable SetScreenState; error=0x%X", __FUNCTION__, status); + return; + } + else + { + sNfaSetPowerSubState.wait(); + } + } + if (state == NFA_SCREEN_STATE_OFF_LOCKED || state == NFA_SCREEN_STATE_OFF_UNLOCKED) + { + // disable both poll and listen on DH 0x02 + discovry_param = NFA_POLLING_DH_DISABLE_MASK | NFA_LISTEN_DH_NFCEE_DISABLE_MASK; + } + + if (state == NFA_SCREEN_STATE_ON_LOCKED) + { + // disable poll and enable listen on DH 0x00 + discovry_param = (screen_state_mask & NFA_SCREEN_POLLING_TAG_MASK) ? + (NFA_LISTEN_DH_NFCEE_ENABLE_MASK | NFA_POLLING_DH_ENABLE_MASK): + (NFA_POLLING_DH_DISABLE_MASK | NFA_LISTEN_DH_NFCEE_ENABLE_MASK); + } + + if (state == NFA_SCREEN_STATE_ON_UNLOCKED) + { + // enable both poll and listen on DH 0x01 + discovry_param = NFA_LISTEN_DH_NFCEE_ENABLE_MASK | NFA_POLLING_DH_ENABLE_MASK; + } + + SyncEventGuard guard (sNfaSetConfigEvent); + status = NFA_SetConfig(NFC_PMID_CON_DISCOVERY_PARAM, NCI_PARAM_LEN_CON_DISCOVERY_PARAM, &discovry_param); + if (status == NFA_STATUS_OK) + { + sNfaSetConfigEvent.wait (); + } else { + ALOGE ("%s: Failed to update CON_DISCOVER_PARAM", __FUNCTION__); + return; + } + + if (prevScreenState == NFA_SCREEN_STATE_ON_LOCKED || prevScreenState == NFA_SCREEN_STATE_ON_UNLOCKED) + { + SyncEventGuard guard (sNfaSetPowerSubState); + status = NFA_SetPowerSubStateForScreenState(state); + if (status != NFA_STATUS_OK) + { + ALOGE ("%s: fail enable SetScreenState; error=0x%X", __FUNCTION__, status); + } else { + sNfaSetPowerSubState.wait(); + } + } + prevScreenState = state; +} /******************************************************************************* ** ** Function: nfcManager_doSetP2pInitiatorModes @@ -1791,11 +1874,17 @@ static JNINativeMethod gMethods[] = {"doEnableScreenOffSuspend", "()V", (void *)nfcManager_doEnableScreenOffSuspend}, + {"doSetScreenState", "(I)V", + (void*)nfcManager_doSetScreenState}, + {"doDisableScreenOffSuspend", "()V", (void *)nfcManager_doDisableScreenOffSuspend}, {"doDump", "()Ljava/lang/String;", (void *)nfcManager_doDump}, + + {"getNciVersion","()I", + (void *)nfcManager_doGetNciVersion}, }; diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java index ecd8e6d3..b1e4d0f5 100755 --- a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java +++ b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java @@ -143,6 +143,12 @@ public class NativeNfcManager implements DeviceHost { @Override public native int getLfT3tMax(); + @Override + public native void doSetScreenState(int screen_state_mask); + + @Override + public native int getNciVersion(); + private native void doEnableDiscovery(int techMask, boolean enableLowPowerPolling, boolean enableReaderMode, diff --git a/src/com/android/nfc/DeviceHost.java b/src/com/android/nfc/DeviceHost.java index 621478c8..b9aad27d 100644 --- a/src/com/android/nfc/DeviceHost.java +++ b/src/com/android/nfc/DeviceHost.java @@ -237,4 +237,8 @@ public interface DeviceHost { boolean enableScreenOffSuspend(); boolean disableScreenOffSuspend(); + + public void doSetScreenState(int screen_state_mask); + + public int getNciVersion(); } diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index 43de15f6..76354852 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -131,6 +131,7 @@ public class NfcService implements DeviceHostListener { static final int MSG_DEREGISTER_T3T_IDENTIFIER = 13; static final int MSG_TAG_DEBOUNCE = 14; static final int MSG_UPDATE_STATS = 15; + static final int MSG_APPLY_SCREEN_STATE = 16; // Update stats every 4 hours static final long STATS_UPDATE_INTERVAL_MS = 4 * 60 * 60 * 1000; @@ -178,6 +179,10 @@ public class NfcService implements DeviceHostListener { public static final int SOUND_END = 1; public static final int SOUND_ERROR = 2; + public static final int NCI_VERSION_2_0 = 0x20; + + public static final int NCI_VERSION_1_0 = 0x10; + public static final String ACTION_LLCP_UP = "com.android.nfc.action.LLCP_UP"; @@ -189,6 +194,7 @@ public class NfcService implements DeviceHostListener { private final UserManager mUserManager; + private static int nci_version = NCI_VERSION_1_0; // NFC Execution Environment // fields below are protected by this private final ReaderModeDeathRecipient mReaderModeDeathRecipient = @@ -620,6 +626,8 @@ public class NfcService implements DeviceHostListener { mCardEmulationManager.onNfcEnabled(); } + nci_version = getNciVersion(); + synchronized (NfcService.this) { mObjectMap.clear(); mP2pLinkManager.enableDisable(mIsNdefPushEnabled, true); @@ -628,6 +636,15 @@ public class NfcService implements DeviceHostListener { initSoundPool(); + mScreenState = mScreenStateHelper.checkScreenState(); + int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? + (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; + + if(mNfcUnlockManager.isLockscreenPollingEnabled()) + applyRouting(false); + + mDeviceHost.doSetScreenState(screen_state_mask); + /* Start polling loop */ applyRouting(true); @@ -1748,6 +1765,10 @@ public class NfcService implements DeviceHostListener { sendMessage(MSG_UNROUTE_AID, aid); } + public int getNciVersion() { + return mDeviceHost.getNciVersion(); + } + private byte[] getT3tIdentifierBytes(String systemCode, String nfcId2, String t3tPmm) { ByteBuffer buffer = ByteBuffer.allocate(2 + 8 + 8); /* systemcode + nfcid2 + t3tpmm */ buffer.put(hexStringToBytes(systemCode)); @@ -2041,6 +2062,22 @@ public class NfcService implements DeviceHostListener { removeMessages(MSG_UPDATE_STATS); sendEmptyMessageDelayed(MSG_UPDATE_STATS, STATS_UPDATE_INTERVAL_MS); break; + + case MSG_APPLY_SCREEN_STATE: + mScreenState = (Integer)msg.obj; + + if (mScreenState == ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED) { + applyRouting(false); + } + int screen_state_mask = (mNfcUnlockManager.isLockscreenPollingEnabled()) ? + (ScreenStateHelper.SCREEN_POLLING_TAG_MASK | mScreenState) : mScreenState; + + if (mNfcUnlockManager.isLockscreenPollingEnabled()) + applyRouting(false); + + mDeviceHost.doSetScreenState(screen_state_mask); + break; + default: Log.e(TAG, "Unknown message received"); break; @@ -2203,9 +2240,12 @@ public class NfcService implements DeviceHostListener { || action.equals(Intent.ACTION_SCREEN_OFF) || action.equals(Intent.ACTION_USER_PRESENT)) { // Perform applyRouting() in AsyncTask to serialize blocking calls - int screenState = ScreenStateHelper.SCREEN_STATE_OFF; + int screenState = mScreenStateHelper.checkScreenState(); if (action.equals(Intent.ACTION_SCREEN_OFF)) { - screenState = ScreenStateHelper.SCREEN_STATE_OFF; + if (mScreenState != ScreenStateHelper.SCREEN_STATE_OFF_LOCKED) { + screenState = mKeyguard.isKeyguardLocked() ? + ScreenStateHelper.SCREEN_STATE_OFF_LOCKED : ScreenStateHelper.SCREEN_STATE_OFF_UNLOCKED; + } } else if (action.equals(Intent.ACTION_SCREEN_ON)) { screenState = mKeyguard.isKeyguardLocked() ? ScreenStateHelper.SCREEN_STATE_ON_LOCKED @@ -2213,8 +2253,10 @@ public class NfcService implements DeviceHostListener { } else if (action.equals(Intent.ACTION_USER_PRESENT)) { screenState = ScreenStateHelper.SCREEN_STATE_ON_UNLOCKED; } - - new ApplyRoutingTask().execute(Integer.valueOf(screenState)); + if (nci_version != NCI_VERSION_2_0) { + new ApplyRoutingTask().execute(Integer.valueOf(screenState)); + } + sendMessage(NfcService.MSG_APPLY_SCREEN_STATE, screenState); } else if (action.equals(Intent.ACTION_USER_SWITCHED)) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); synchronized (this) { diff --git a/src/com/android/nfc/ScreenStateHelper.java b/src/com/android/nfc/ScreenStateHelper.java index b044c287..92ba1687 100644 --- a/src/com/android/nfc/ScreenStateHelper.java +++ b/src/com/android/nfc/ScreenStateHelper.java @@ -9,10 +9,16 @@ import android.os.PowerManager; */ class ScreenStateHelper { - static final int SCREEN_STATE_UNKNOWN = 0; - static final int SCREEN_STATE_OFF = 1; - static final int SCREEN_STATE_ON_LOCKED = 2; - static final int SCREEN_STATE_ON_UNLOCKED = 3; + static final int SCREEN_STATE_UNKNOWN = 0x00; + static final int SCREEN_STATE_OFF_UNLOCKED = 0x01; + static final int SCREEN_STATE_OFF_LOCKED = 0x02; + static final int SCREEN_STATE_ON_LOCKED = 0x04; + static final int SCREEN_STATE_ON_UNLOCKED = 0x08; + + //Polling mask + static final int SCREEN_POLLING_TAG_MASK = 0x10; + static final int SCREEN_POLLING_P2P_MASK = 0x20; + static final int SCREEN_POLLING_READER_MASK = 0x40; private final PowerManager mPowerManager; private final KeyguardManager mKeyguardManager; @@ -26,7 +32,11 @@ class ScreenStateHelper { int checkScreenState() { //TODO: fix deprecated api if (!mPowerManager.isScreenOn()) { - return SCREEN_STATE_OFF; + if(mKeyguardManager.isKeyguardLocked()) { + return SCREEN_STATE_OFF_LOCKED; + } else { + return SCREEN_STATE_OFF_UNLOCKED; + } } else if (mKeyguardManager.isKeyguardLocked()) { return SCREEN_STATE_ON_LOCKED; } else { @@ -39,12 +49,14 @@ class ScreenStateHelper { */ static String screenStateToString(int screenState) { switch (screenState) { - case SCREEN_STATE_OFF: - return "OFF"; + case SCREEN_STATE_OFF_LOCKED: + return "OFF_LOCKED"; case SCREEN_STATE_ON_LOCKED: return "ON_LOCKED"; case SCREEN_STATE_ON_UNLOCKED: return "ON_UNLOCKED"; + case SCREEN_STATE_OFF_UNLOCKED: + return "OFF_UNLOCKED"; default: return "UNKNOWN"; } |