diff options
| -rw-r--r-- | api/current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/nfc/cardemulation/HostApduService.java | 83 |
2 files changed, 86 insertions, 1 deletions
diff --git a/api/current.txt b/api/current.txt index b252864628bf..118737ff706f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -15115,9 +15115,11 @@ package android.nfc.cardemulation { public abstract class HostApduService extends android.app.Service { ctor public HostApduService(); + method public final void notifyUnhandled(); method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onDeactivated(int); - method public abstract byte[] processCommandApdu(byte[], int); + method public byte[] processCommandApdu(byte[], android.os.Bundle); + method public abstract deprecated byte[] processCommandApdu(byte[], int); method public final void sendResponseApdu(byte[]); field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java index 6d091c1f3d13..cdc4adbcc025 100644 --- a/core/java/android/nfc/cardemulation/HostApduService.java +++ b/core/java/android/nfc/cardemulation/HostApduService.java @@ -4,11 +4,13 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.Service; import android.content.Intent; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; +import android.os.Parcel; import android.os.RemoteException; import android.util.Log; @@ -98,6 +100,12 @@ public abstract class HostApduService extends Service { public static final int MSG_DEACTIVATED = 2; /** + * + * @hide + */ + public static final int MSG_UNHANDLED = 3; + + /** * @hide */ public static final String KEY_DATA = "data"; @@ -105,6 +113,8 @@ public abstract class HostApduService extends Service { /** * Messenger interface to NfcService for sending responses. * Only accessed on main thread by the message handler. + * + * @hide */ Messenger mNfcService = null; @@ -133,6 +143,7 @@ public abstract class HostApduService extends Service { Bundle responseBundle = new Bundle(); responseBundle.putByteArray(KEY_DATA, responseApdu); responseMsg.setData(responseBundle); + responseMsg.replyTo = mMessenger; try { mNfcService.send(responseMsg); } catch (RemoteException e) { @@ -150,6 +161,7 @@ public abstract class HostApduService extends Service { return; } try { + msg.replyTo = mMessenger; mNfcService.send(msg); } catch (RemoteException e) { Log.e(TAG, "RemoteException calling into NfcService."); @@ -160,6 +172,18 @@ public abstract class HostApduService extends Service { mNfcService = null; onDeactivated(msg.arg1); break; + case MSG_UNHANDLED: + if (mNfcService == null) { + Log.e(TAG, "notifyUnhandled not sent; service was deactivated."); + return; + } + try { + msg.replyTo = mMessenger; + mNfcService.send(msg); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException calling into NfcService."); + } + break; default: super.handleMessage(msg); } @@ -190,6 +214,64 @@ public abstract class HostApduService extends Service { } /** + * Calling this method allows the service to tell the OS + * that it won't be able to complete this transaction - + * for example, because it requires data connectivity + * that is not present at that moment. + * + * The OS may use this indication to give the user a list + * of alternative applications that can handle the last + * AID that was selected. If the user would select an + * application from the list, that action by itself + * will not cause the default to be changed; the selected + * application will be invoked for the next tap only. + * + * If there are no other applications that can handle + * this transaction, the OS will show an error dialog + * indicating your service could not complete the + * transaction. + * + * <p>Note: this method may be called anywhere between + * the first {@link #processCommandApdu(byte[], int)} + * call and a {@link #onDeactivated(int)} call. + */ + public final void notifyUnhandled() { + Message unhandledMsg = Message.obtain(null, MSG_UNHANDLED); + try { + mMessenger.send(unhandledMsg); + } catch (RemoteException e) { + Log.e("TAG", "Local messenger has died."); + } + } + + + /** + * <p>This method will be called when a command APDU has been received + * from a remote device. A response APDU can be provided directly + * by returning a byte-array in this method. Note that in general + * response APDUs must be sent as quickly as possible, given the fact + * that the user is likely holding his device over an NFC reader + * when this method is called. + * + * <p class="note">If there are multiple services that have registered for the same + * AIDs in their meta-data entry, you will only get called if the user has + * explicitly selected your service, either as a default or just for the next tap. + * + * <p class="note">This method is running on the main thread of your application. + * If you cannot return a response APDU immediately, return null + * and use the {@link #sendResponseApdu(byte[])} method later. + * + * @param commandApdu The APDU that received from the remote device + * @param extras A bundle containing extra data. May be null. + * @return a byte-array containing the response APDU, or null if no + * response APDU can be sent at this point. + */ + public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) { + // TODO make this abstract + return processCommandApdu(commandApdu, 0); + } + + /** * <p>This method will be called when a command APDU has been received * from a remote device. A response APDU can be provided directly * by returning a byte-array in this method. Note that in general @@ -205,6 +287,7 @@ public abstract class HostApduService extends Service { * If you cannot return a response APDU immediately, return null * and use the {@link #sendResponseApdu(byte[])} method later. * + * @deprecated use {@link #processCommandApdu(byte[], Bundle)} * @param commandApdu * @param flags * @return a byte-array containing the response APDU, or null if no |