From 131197aa6e6b0ae91fefe4bb5f39fffb780997c5 Mon Sep 17 00:00:00 2001 From: Andres Morales Date: Wed, 23 Jul 2014 12:39:55 -0700 Subject: NFC Unlock api changes Bug: 16401635 Change-Id: I138a9aa0bb156982b6c7656c51a1e2194776e4ed --- core/java/android/nfc/INfcAdapter.aidl | 3 + core/java/android/nfc/INfcUnlockHandler.aidl | 12 ++++ core/java/android/nfc/NfcAdapter.java | 89 +++++++++++++++++++++++++++- core/java/android/nfc/Tag.java | 2 +- 4 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 core/java/android/nfc/INfcUnlockHandler.aidl (limited to 'core') diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index 541b700..ee4d45e 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -27,6 +27,7 @@ import android.nfc.INfcAdapterExtras; import android.nfc.INfcTag; import android.nfc.INfcCardEmulation; import android.nfc.INfcLockscreenDispatch; +import android.nfc.INfcUnlockHandler; import android.os.Bundle; /** @@ -57,4 +58,6 @@ interface INfcAdapter void setP2pModes(int initatorModes, int targetModes); void registerLockscreenDispatch(INfcLockscreenDispatch lockscreenDispatch, in int[] techList); + void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList); + void removeNfcUnlockHandler(IBinder b); } diff --git a/core/java/android/nfc/INfcUnlockHandler.aidl b/core/java/android/nfc/INfcUnlockHandler.aidl new file mode 100644 index 0000000..e1cace9 --- /dev/null +++ b/core/java/android/nfc/INfcUnlockHandler.aidl @@ -0,0 +1,12 @@ +package android.nfc; + +import android.nfc.Tag; + +/** + * @hide + */ +interface INfcUnlockHandler { + + boolean onUnlockAttempted(in Tag tag); + +} diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index ad785ed..dde2cf1 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -30,7 +30,6 @@ import android.content.IntentFilter; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.net.Uri; -import android.nfc.BeamShareData; import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import android.nfc.tech.NfcA; @@ -312,6 +311,8 @@ public final class NfcAdapter { final NfcActivityManager mNfcActivityManager; final Context mContext; + final HashMap mNfcUnlockHandlers; + final Object mLock; /** * A callback to be invoked when the system finds a tag while the foreground activity is @@ -394,6 +395,22 @@ public final class NfcAdapter { /** + * A callback to be invoked when an application has registered as a + * handler to unlock the device given an NFC tag at the lockscreen. + * @hide + */ + @SystemApi + public interface NfcUnlockHandler { + /** + * Called at the lock screen to attempt to unlock the device with the given tag. + * @param tag the detected tag, to be used to unlock the device + * @return true if the device was successfully unlocked + */ + public boolean onUnlockAttempted(Tag tag); + } + + + /** * Helper to check if this device has FEATURE_NFC, but without using * a context. * Equivalent to @@ -525,6 +542,8 @@ public final class NfcAdapter { NfcAdapter(Context context) { mContext = context; mNfcActivityManager = new NfcActivityManager(this); + mNfcUnlockHandlers = new HashMap(); + mLock = new Object(); } /** @@ -1457,7 +1476,50 @@ public final class NfcAdapter { public boolean onTagDetected(Tag tag) throws RemoteException { return lockscreenDispatch.onTagDetected(tag); } - }, Tag.techListFromStrings(techList)); + }, Tag.getTechCodesFromStrings(techList)); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + return false; + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unable to register LockscreenDispatch", e); + return false; + } + + return true; + } + + /** + * Registers a new NFC unlock handler with the NFC service. + * + *

NFC unlock handlers are intended to unlock the keyguard in the presence of a trusted + * NFC device. The handler should return true if it successfully authenticates the user and + * unlocks the keyguard. + * + *

The parameter {@code tagTechnologies} determines which Tag technologies will be polled for + * at the lockscreen. Polling for less tag technologies reduces latency, and so it is + * strongly recommended to only provide the Tag technologies that the handler is expected to + * receive. + * + * @hide + */ + @SystemApi + public boolean addNfcUnlockHandler(final NfcUnlockHandler unlockHandler, + String[] tagTechnologies) { + try { + INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() { + @Override + public boolean onUnlockAttempted(Tag tag) throws RemoteException { + return unlockHandler.onUnlockAttempted(tag); + } + }; + + synchronized (mLock) { + if (mNfcUnlockHandlers.containsKey(unlockHandler)) { + return true; + } + sService.addNfcUnlockHandler(iHandler, Tag.getTechCodesFromStrings(tagTechnologies)); + mNfcUnlockHandlers.put(unlockHandler, iHandler.asBinder()); + } } catch (RemoteException e) { attemptDeadServiceRecovery(e); return false; @@ -1470,6 +1532,29 @@ public final class NfcAdapter { } /** + * Removes a previously registered unlock handler. Also removes the tag technologies + * associated with the removed unlock handler. + * + * @hide + */ + @SystemApi + public boolean removeNfcUnlockHandler(NfcUnlockHandler unlockHandler) { + try { + synchronized (mLock) { + if (mNfcUnlockHandlers.containsKey(unlockHandler)) { + sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler)); + mNfcUnlockHandlers.remove(unlockHandler); + } + + return true; + } + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + return false; + } + } + + /** * @hide */ public INfcAdapterExtras getNfcAdapterExtrasInterface() { diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 43be702..154d5a1 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -196,7 +196,7 @@ public final class Tag implements Parcelable { return strings; } - static int[] techListFromStrings(String[] techStringList) throws IllegalArgumentException { + static int[] getTechCodesFromStrings(String[] techStringList) throws IllegalArgumentException { if (techStringList == null) { throw new IllegalArgumentException("List cannot be null"); } -- cgit v1.1