From 3a894dda035a331860f0f23e93528527493a07a3 Mon Sep 17 00:00:00 2001 From: Love Khanna Date: Thu, 11 May 2017 20:31:09 +0530 Subject: 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) --- nci/jni/NativeNfcManager.cpp | 91 +++++++++++++++++++++- .../com/android/nfc/dhimpl/NativeNfcManager.java | 6 ++ src/com/android/nfc/DeviceHost.java | 4 + src/com/android/nfc/NfcService.java | 50 +++++++++++- 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"; } -- cgit v1.2.3