3030import android .content .pm .IPackageManager ;
3131import android .content .pm .PackageManager ;
3232import android .net .Uri ;
33- import android .nfc .BeamShareData ;
3433import android .nfc .tech .MifareClassic ;
3534import android .nfc .tech .Ndef ;
3635import android .nfc .tech .NfcA ;
@@ -312,6 +311,8 @@ public final class NfcAdapter {
312311
313312 final NfcActivityManager mNfcActivityManager ;
314313 final Context mContext ;
314+ final HashMap <NfcUnlockHandler , IBinder > mNfcUnlockHandlers ;
315+ final Object mLock ;
315316
316317 /**
317318 * A callback to be invoked when the system finds a tag while the foreground activity is
@@ -393,6 +394,22 @@ public interface NfcLockscreenDispatch {
393394 }
394395
395396
397+ /**
398+ * A callback to be invoked when an application has registered as a
399+ * handler to unlock the device given an NFC tag at the lockscreen.
400+ * @hide
401+ */
402+ @ SystemApi
403+ public interface NfcUnlockHandler {
404+ /**
405+ * Called at the lock screen to attempt to unlock the device with the given tag.
406+ * @param tag the detected tag, to be used to unlock the device
407+ * @return true if the device was successfully unlocked
408+ */
409+ public boolean onUnlockAttempted (Tag tag );
410+ }
411+
412+
396413 /**
397414 * Helper to check if this device has FEATURE_NFC, but without using
398415 * a context.
@@ -525,6 +542,8 @@ public static NfcAdapter getDefaultAdapter() {
525542 NfcAdapter (Context context ) {
526543 mContext = context ;
527544 mNfcActivityManager = new NfcActivityManager (this );
545+ mNfcUnlockHandlers = new HashMap <NfcUnlockHandler , IBinder >();
546+ mLock = new Object ();
528547 }
529548
530549 /**
@@ -1457,7 +1476,50 @@ public boolean registerLockscreenDispatch(final NfcLockscreenDispatch lockscreen
14571476 public boolean onTagDetected (Tag tag ) throws RemoteException {
14581477 return lockscreenDispatch .onTagDetected (tag );
14591478 }
1460- }, Tag .techListFromStrings (techList ));
1479+ }, Tag .getTechCodesFromStrings (techList ));
1480+ } catch (RemoteException e ) {
1481+ attemptDeadServiceRecovery (e );
1482+ return false ;
1483+ } catch (IllegalArgumentException e ) {
1484+ Log .e (TAG , "Unable to register LockscreenDispatch" , e );
1485+ return false ;
1486+ }
1487+
1488+ return true ;
1489+ }
1490+
1491+ /**
1492+ * Registers a new NFC unlock handler with the NFC service.
1493+ *
1494+ * <p />NFC unlock handlers are intended to unlock the keyguard in the presence of a trusted
1495+ * NFC device. The handler should return true if it successfully authenticates the user and
1496+ * unlocks the keyguard.
1497+ *
1498+ * <p /> The parameter {@code tagTechnologies} determines which Tag technologies will be polled for
1499+ * at the lockscreen. Polling for less tag technologies reduces latency, and so it is
1500+ * strongly recommended to only provide the Tag technologies that the handler is expected to
1501+ * receive.
1502+ *
1503+ * @hide
1504+ */
1505+ @ SystemApi
1506+ public boolean addNfcUnlockHandler (final NfcUnlockHandler unlockHandler ,
1507+ String [] tagTechnologies ) {
1508+ try {
1509+ INfcUnlockHandler .Stub iHandler = new INfcUnlockHandler .Stub () {
1510+ @ Override
1511+ public boolean onUnlockAttempted (Tag tag ) throws RemoteException {
1512+ return unlockHandler .onUnlockAttempted (tag );
1513+ }
1514+ };
1515+
1516+ synchronized (mLock ) {
1517+ if (mNfcUnlockHandlers .containsKey (unlockHandler )) {
1518+ return true ;
1519+ }
1520+ sService .addNfcUnlockHandler (iHandler , Tag .getTechCodesFromStrings (tagTechnologies ));
1521+ mNfcUnlockHandlers .put (unlockHandler , iHandler .asBinder ());
1522+ }
14611523 } catch (RemoteException e ) {
14621524 attemptDeadServiceRecovery (e );
14631525 return false ;
@@ -1469,6 +1531,29 @@ public boolean onTagDetected(Tag tag) throws RemoteException {
14691531 return true ;
14701532 }
14711533
1534+ /**
1535+ * Removes a previously registered unlock handler. Also removes the tag technologies
1536+ * associated with the removed unlock handler.
1537+ *
1538+ * @hide
1539+ */
1540+ @ SystemApi
1541+ public boolean removeNfcUnlockHandler (NfcUnlockHandler unlockHandler ) {
1542+ try {
1543+ synchronized (mLock ) {
1544+ if (mNfcUnlockHandlers .containsKey (unlockHandler )) {
1545+ sService .removeNfcUnlockHandler (mNfcUnlockHandlers .get (unlockHandler ));
1546+ mNfcUnlockHandlers .remove (unlockHandler );
1547+ }
1548+
1549+ return true ;
1550+ }
1551+ } catch (RemoteException e ) {
1552+ attemptDeadServiceRecovery (e );
1553+ return false ;
1554+ }
1555+ }
1556+
14721557 /**
14731558 * @hide
14741559 */
0 commit comments