summaryrefslogtreecommitdiffstats
path: root/core/java/android/nfc
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-09-02 20:38:47 -0700
committerMartijn Coenen <maco@google.com>2013-09-02 20:43:57 -0700
commit5b1e032ea7c06ab11d778264dd950009fcb93cc5 (patch)
tree69b8691184cde10bbf629921a4a17e0e419f7078 /core/java/android/nfc
parent52c10e94d98e32d977bfd4021136f4c9fa571bd6 (diff)
downloadframeworks_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.aidl7
-rw-r--r--core/java/android/nfc/NfcActivityManager.java47
-rw-r--r--core/java/android/nfc/NfcAdapter.java49
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);
}
/**