1 package com.android.nfc; 2 3 import android.nfc.INfcUnlockHandler; 4 import android.nfc.Tag; 5 import android.os.IBinder; 6 import android.util.Log; 7 8 import java.util.HashMap; 9 import java.util.Iterator; 10 11 /** 12 * Singleton for handling NFC Unlock related logic and state. 13 */ 14 class NfcUnlockManager { 15 private static final String TAG = "NfcUnlockManager"; 16 17 private final HashMap<IBinder, UnlockHandlerWrapper> mUnlockHandlers; 18 private int mLockscreenPollMask; 19 20 private static class UnlockHandlerWrapper { 21 final INfcUnlockHandler mUnlockHandler; 22 final int mPollMask; 23 24 UnlockHandlerWrapper(INfcUnlockHandler unlockHandler, int pollMask)25 private UnlockHandlerWrapper(INfcUnlockHandler unlockHandler, int pollMask) { 26 mUnlockHandler = unlockHandler; 27 mPollMask = pollMask; 28 } 29 } 30 getInstance()31 public static NfcUnlockManager getInstance() { 32 return Singleton.INSTANCE; 33 } 34 35 addUnlockHandler(INfcUnlockHandler unlockHandler, int pollMask)36 synchronized int addUnlockHandler(INfcUnlockHandler unlockHandler, int pollMask) { 37 if (mUnlockHandlers.containsKey(unlockHandler.asBinder())) { 38 return mLockscreenPollMask; 39 } 40 41 mUnlockHandlers.put(unlockHandler.asBinder(), 42 new UnlockHandlerWrapper(unlockHandler, pollMask)); 43 return (mLockscreenPollMask |= pollMask); 44 } 45 removeUnlockHandler(IBinder unlockHandler)46 synchronized int removeUnlockHandler(IBinder unlockHandler) { 47 if (mUnlockHandlers.containsKey(unlockHandler)) { 48 mUnlockHandlers.remove(unlockHandler); 49 mLockscreenPollMask = recomputePollMask(); 50 } 51 52 return mLockscreenPollMask; 53 } 54 tryUnlock(Tag tag)55 synchronized boolean tryUnlock(Tag tag) { 56 Iterator<IBinder> iterator = mUnlockHandlers.keySet().iterator(); 57 while (iterator.hasNext()) { 58 try { 59 IBinder binder = iterator.next(); 60 UnlockHandlerWrapper handlerWrapper = mUnlockHandlers.get(binder); 61 if (handlerWrapper.mUnlockHandler.onUnlockAttempted(tag)) { 62 return true; 63 } 64 } catch (Exception e) { 65 Log.e(TAG, "failed to communicate with unlock handler, removing", e); 66 iterator.remove(); 67 mLockscreenPollMask = recomputePollMask(); 68 } 69 } 70 71 return false; 72 } 73 recomputePollMask()74 private int recomputePollMask() { 75 int pollMask = 0; 76 for (UnlockHandlerWrapper wrapper : mUnlockHandlers.values()) { 77 pollMask |= wrapper.mPollMask; 78 } 79 return pollMask; 80 } 81 getLockscreenPollMask()82 synchronized int getLockscreenPollMask() { 83 return mLockscreenPollMask; 84 } 85 isLockscreenPollingEnabled()86 synchronized boolean isLockscreenPollingEnabled() { 87 return mLockscreenPollMask != 0; 88 } 89 90 private static class Singleton { 91 private static final NfcUnlockManager INSTANCE = new NfcUnlockManager(); 92 } 93 NfcUnlockManager()94 private NfcUnlockManager() { 95 mUnlockHandlers = new HashMap<IBinder, UnlockHandlerWrapper>(); 96 mLockscreenPollMask = 0; 97 } 98 } 99 100