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