diff options
author | Martijn Coenen <maco@google.com> | 2013-09-02 20:38:47 -0700 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2013-09-02 20:43:57 -0700 |
commit | 5b1e032ea7c06ab11d778264dd950009fcb93cc5 (patch) | |
tree | 69b8691184cde10bbf629921a4a17e0e419f7078 /core/java/android/nfc | |
parent | 52c10e94d98e32d977bfd4021136f4c9fa571bd6 (diff) | |
download | frameworks_base-5b1e032ea7c06ab11d778264dd950009fcb93cc5.zip frameworks_base-5b1e032ea7c06ab11d778264dd950009fcb93cc5.tar.gz frameworks_base-5b1e032ea7c06ab11d778264dd950009fcb93cc5.tar.bz2 |
Reader mode NFC API: move to callback model.
Using intents for reader mode doesn't work well for 2 reasons:
1) Intents are used to resolve, but in reader mode we already
know where to resolve to. Additionally, dispatching an intent
causes additional latency.
2) Using intents with foreground dispatch was tricky; for every
call to onNewIntent() with a new tag, there was a call to
onPause(), which effectively disabled reader mode again,
causing a discovery loop.
Instead, let the app register a callback, and call that when
we discover a new tag. Also, add new flag to disable platform
sounds, and to change the presence check delay.
Bug: 10360259
Change-Id: I8373543d6cf2f7ca73c9b3e42bb8b51e3ac48cac
Diffstat (limited to 'core/java/android/nfc')
-rw-r--r-- | core/java/android/nfc/IAppCallback.aidl (renamed from core/java/android/nfc/INdefPushCallback.aidl) | 4 | ||||
-rw-r--r-- | core/java/android/nfc/INfcAdapter.aidl | 7 | ||||
-rw-r--r-- | core/java/android/nfc/NfcActivityManager.java | 47 | ||||
-rw-r--r-- | core/java/android/nfc/NfcAdapter.java | 49 |
4 files changed, 81 insertions, 26 deletions
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/IAppCallback.aidl index 16771dc..9599308 100644 --- a/core/java/android/nfc/INdefPushCallback.aidl +++ b/core/java/android/nfc/IAppCallback.aidl @@ -17,12 +17,14 @@ package android.nfc; import android.nfc.BeamShareData; +import android.nfc.Tag; /** * @hide */ -interface INdefPushCallback +interface IAppCallback { BeamShareData createBeamShareData(); void onNdefPushComplete(); + void onTagDiscovered(in Tag tag); } diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index 15d0475..8414738 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -21,10 +21,11 @@ import android.content.IntentFilter; import android.nfc.NdefMessage; import android.nfc.Tag; import android.nfc.TechListParcel; -import android.nfc.INdefPushCallback; +import android.nfc.IAppCallback; import android.nfc.INfcAdapterExtras; import android.nfc.INfcTag; import android.nfc.INfcCardEmulation; +import android.os.Bundle; /** * @hide @@ -44,10 +45,10 @@ interface INfcAdapter void setForegroundDispatch(in PendingIntent intent, in IntentFilter[] filters, in TechListParcel techLists); - void setNdefPushCallback(in INdefPushCallback callback); + void setAppCallback(in IAppCallback callback); void dispatch(in Tag tag); - void setReaderMode (IBinder b, int flags); + void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras); void setP2pModes(int initatorModes, int targetModes); } diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java index d0d943c..77c0234 100644 --- a/core/java/android/nfc/NfcActivityManager.java +++ b/core/java/android/nfc/NfcActivityManager.java @@ -19,6 +19,7 @@ package android.nfc; import android.app.Activity; import android.app.Application; import android.net.Uri; +import android.nfc.NfcAdapter.ReaderCallback; import android.os.Binder; import android.os.Bundle; import android.os.RemoteException; @@ -36,7 +37,7 @@ import java.util.List; * * @hide */ -public final class NfcActivityManager extends INdefPushCallback.Stub +public final class NfcActivityManager extends IAppCallback.Stub implements Application.ActivityLifecycleCallbacks { static final String TAG = NfcAdapter.TAG; static final Boolean DBG = false; @@ -113,6 +114,8 @@ public final class NfcActivityManager extends INdefPushCallback.Stub Uri[] uris = null; int flags = 0; int readerModeFlags = 0; + NfcAdapter.ReaderCallback readerCallback = null; + Bundle readerModeExtras = null; Binder token; public NfcActivityState(Activity activity) { @@ -197,17 +200,20 @@ public final class NfcActivityManager extends INdefPushCallback.Stub mDefaultEvent = new NfcEvent(mAdapter); } - public void enableReaderMode(Activity activity, int flags) { + public void enableReaderMode(Activity activity, ReaderCallback callback, int flags, + Bundle extras) { boolean isResumed; Binder token; synchronized (NfcActivityManager.this) { NfcActivityState state = getActivityState(activity); + state.readerCallback = callback; state.readerModeFlags = flags; + state.readerModeExtras = extras; token = state.token; isResumed = state.resumed; } if (isResumed) { - setReaderMode(token, flags); + setReaderMode(token, flags, extras); } } @@ -216,20 +222,22 @@ public final class NfcActivityManager extends INdefPushCallback.Stub Binder token; synchronized (NfcActivityManager.this) { NfcActivityState state = getActivityState(activity); + state.readerCallback = null; state.readerModeFlags = 0; + state.readerModeExtras = null; token = state.token; isResumed = state.resumed; } if (isResumed) { - setReaderMode(token, 0); + setReaderMode(token, 0, null); } } - public void setReaderMode(Binder token, int flags) { + public void setReaderMode(Binder token, int flags, Bundle extras) { if (DBG) Log.d(TAG, "Setting reader mode"); try { - NfcAdapter.sService.setReaderMode(token, flags); + NfcAdapter.sService.setReaderMode(token, this, flags, extras); } catch (RemoteException e) { mAdapter.attemptDeadServiceRecovery(e); } @@ -302,12 +310,12 @@ public final class NfcActivityManager extends INdefPushCallback.Stub } /** - * Request or unrequest NFC service callbacks for NDEF push. + * Request or unrequest NFC service callbacks. * Makes IPC call - do not hold lock. */ void requestNfcServiceCallback() { try { - NfcAdapter.sService.setNdefPushCallback(this); + NfcAdapter.sService.setAppCallback(this); } catch (RemoteException e) { mAdapter.attemptDeadServiceRecovery(e); } @@ -375,6 +383,22 @@ public final class NfcActivityManager extends INdefPushCallback.Stub } } + @Override + public void onTagDiscovered(Tag tag) throws RemoteException { + NfcAdapter.ReaderCallback callback; + synchronized (NfcActivityManager.this) { + NfcActivityState state = findResumedActivityState(); + if (state == null) return; + + callback = state.readerCallback; + } + + // Make callback without lock + if (callback != null) { + callback.onTagDiscovered(tag); + } + + } /** Callback from Activity life-cycle, on main thread */ @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ } @@ -387,6 +411,7 @@ public final class NfcActivityManager extends INdefPushCallback.Stub @Override public void onActivityResumed(Activity activity) { int readerModeFlags = 0; + Bundle readerModeExtras = null; Binder token; synchronized (NfcActivityManager.this) { NfcActivityState state = findActivityState(activity); @@ -395,9 +420,10 @@ public final class NfcActivityManager extends INdefPushCallback.Stub state.resumed = true; token = state.token; readerModeFlags = state.readerModeFlags; + readerModeExtras = state.readerModeExtras; } if (readerModeFlags != 0) { - setReaderMode(token, readerModeFlags); + setReaderMode(token, readerModeFlags, readerModeExtras); } requestNfcServiceCallback(); } @@ -417,7 +443,7 @@ public final class NfcActivityManager extends INdefPushCallback.Stub } if (readerModeFlagsSet) { // Restore default p2p modes - setReaderMode(token, 0); + setReaderMode(token, 0, null); } } @@ -441,4 +467,5 @@ public final class NfcActivityManager extends INdefPushCallback.Stub } } } + } diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index fa0c1f6..2a18900 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -33,6 +33,7 @@ import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import android.nfc.tech.NfcA; import android.nfc.tech.NfcF; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -196,42 +197,42 @@ public final class NfcAdapter { public static final int STATE_TURNING_OFF = 4; /** - * Flag for use with {@link #enableReaderMode(Activity, int)}. + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. * <p> * Setting this flag enables polling for Nfc-A technology. */ public static final int FLAG_READER_NFC_A = 0x1; /** - * Flag for use with {@link #enableReaderMode(Activity, int)}. + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. * <p> * Setting this flag enables polling for Nfc-B technology. */ public static final int FLAG_READER_NFC_B = 0x2; /** - * Flag for use with {@link #enableReaderMode(Activity, int)}. + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. * <p> * Setting this flag enables polling for Nfc-F technology. */ public static final int FLAG_READER_NFC_F = 0x4; /** - * Flag for use with {@link #enableReaderMode(Activity, int)}. + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. * <p> * Setting this flag enables polling for Nfc-V (ISO15693) technology. */ public static final int FLAG_READER_NFC_V = 0x8; /** - * Flag for use with {@link #enableReaderMode(Activity, int)}. + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. * <p> * Setting this flag enables polling for Kovio technology. */ public static final int FLAG_READER_KOVIO = 0x10; /** - * Flag for use with {@link #enableReaderMode(Activity, int)}. + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. * <p> * Setting this flag allows the caller to prevent the * platform from performing an NDEF check on the tags it @@ -239,6 +240,23 @@ public final class NfcAdapter { */ public static final int FLAG_READER_SKIP_NDEF_CHECK = 0x80; + /** + * Flag for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. + * <p> + * Setting this flag allows the caller to prevent the + * platform from playing sounds when it discovers a tag. + */ + public static final int FLAG_READER_NO_PLATFORM_SOUNDS = 0x100; + + /** + * Int Extra for use with {@link #enableReaderMode(Activity, ReaderCallback, int, Bundle)}. + * <p> + * Setting this integer extra allows the calling application to specify + * the delay that the platform will use for performing presence checks + * on any discovered tag. + */ + public static final String EXTRA_READER_PRESENCE_CHECK_DELAY = "presence"; + /** @hide */ public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1; @@ -291,6 +309,14 @@ public final class NfcAdapter { final Context mContext; /** + * A callback to be invoked when the system has found a tag in + * reader mode. + */ + public interface ReaderCallback { + public void onTagDiscovered(Tag tag); + } + + /** * A callback to be invoked when the system successfully delivers your {@link NdefMessage} * to another device. * @see #setOnNdefPushCompleteCallback @@ -1167,19 +1193,18 @@ public final class NfcAdapter { * {@link Ndef} tag technology from being enumerated on the tag, and that * NDEF-based tag dispatch will not be functional. * - * <p>It is recommended to combine this method with - * {@link #enableForegroundDispatch(Activity, PendingIntent, IntentFilter[], String[][]) - * to ensure that tags are delivered to this activity. - * * <p>For interacting with tags that are emulated on another Android device * using Android's host-based card-emulation, the recommended flags are * {@link #FLAG_READER_NFC_A} and {@link #FLAG_READER_SKIP_NDEF_CHECK}. * * @param activity the Activity that requests the adapter to be in reader mode + * @param callback the callback to be called when a tag is discovered * @param flags Flags indicating poll technologies and other optional parameters + * @param extras Additional extras for configuring reader mode. */ - public void enableReaderMode(Activity activity, int flags) { - mNfcActivityManager.enableReaderMode(activity, flags); + public void enableReaderMode(Activity activity, ReaderCallback callback, int flags, + Bundle extras) { + mNfcActivityManager.enableReaderMode(activity, callback, flags, extras); } /** |