Loading api/current.txt +3 −1 Original line number Original line Diff line number Diff line Loading @@ -15115,9 +15115,11 @@ package android.nfc.cardemulation { public abstract class HostApduService extends android.app.Service { public abstract class HostApduService extends android.app.Service { ctor public HostApduService(); ctor public HostApduService(); method public final void notifyUnhandled(); method public final android.os.IBinder onBind(android.content.Intent); method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onDeactivated(int); 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[]); method public final void sendResponseApdu(byte[]); field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 core/java/android/nfc/cardemulation/HostApduService.java +83 −0 Original line number Original line Diff line number Diff line Loading @@ -4,11 +4,13 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SdkConstant.SdkConstantType; import android.app.Service; import android.app.Service; import android.content.Intent; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Message; import android.os.Message; import android.os.Messenger; import android.os.Messenger; import android.os.Parcel; import android.os.RemoteException; import android.os.RemoteException; import android.util.Log; import android.util.Log; Loading Loading @@ -97,6 +99,12 @@ public abstract class HostApduService extends Service { */ */ public static final int MSG_DEACTIVATED = 2; public static final int MSG_DEACTIVATED = 2; /** * * @hide */ public static final int MSG_UNHANDLED = 3; /** /** * @hide * @hide */ */ Loading @@ -105,6 +113,8 @@ public abstract class HostApduService extends Service { /** /** * Messenger interface to NfcService for sending responses. * Messenger interface to NfcService for sending responses. * Only accessed on main thread by the message handler. * Only accessed on main thread by the message handler. * * @hide */ */ Messenger mNfcService = null; Messenger mNfcService = null; Loading Loading @@ -133,6 +143,7 @@ public abstract class HostApduService extends Service { Bundle responseBundle = new Bundle(); Bundle responseBundle = new Bundle(); responseBundle.putByteArray(KEY_DATA, responseApdu); responseBundle.putByteArray(KEY_DATA, responseApdu); responseMsg.setData(responseBundle); responseMsg.setData(responseBundle); responseMsg.replyTo = mMessenger; try { try { mNfcService.send(responseMsg); mNfcService.send(responseMsg); } catch (RemoteException e) { } catch (RemoteException e) { Loading @@ -150,6 +161,7 @@ public abstract class HostApduService extends Service { return; return; } } try { try { msg.replyTo = mMessenger; mNfcService.send(msg); mNfcService.send(msg); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, "RemoteException calling into NfcService."); Log.e(TAG, "RemoteException calling into NfcService."); Loading @@ -160,6 +172,18 @@ public abstract class HostApduService extends Service { mNfcService = null; mNfcService = null; onDeactivated(msg.arg1); onDeactivated(msg.arg1); break; 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: default: super.handleMessage(msg); super.handleMessage(msg); } } Loading Loading @@ -189,6 +213,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 * <p>This method will be called when a command APDU has been received * from a remote device. A response APDU can be provided directly * from a remote device. A response APDU can be provided directly Loading @@ -205,6 +287,7 @@ public abstract class HostApduService extends Service { * If you cannot return a response APDU immediately, return null * If you cannot return a response APDU immediately, return null * and use the {@link #sendResponseApdu(byte[])} method later. * and use the {@link #sendResponseApdu(byte[])} method later. * * * @deprecated use {@link #processCommandApdu(byte[], Bundle)} * @param commandApdu * @param commandApdu * @param flags * @param flags * @return a byte-array containing the response APDU, or null if no * @return a byte-array containing the response APDU, or null if no Loading Loading
api/current.txt +3 −1 Original line number Original line Diff line number Diff line Loading @@ -15115,9 +15115,11 @@ package android.nfc.cardemulation { public abstract class HostApduService extends android.app.Service { public abstract class HostApduService extends android.app.Service { ctor public HostApduService(); ctor public HostApduService(); method public final void notifyUnhandled(); method public final android.os.IBinder onBind(android.content.Intent); method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onDeactivated(int); 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[]); method public final void sendResponseApdu(byte[]); field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
core/java/android/nfc/cardemulation/HostApduService.java +83 −0 Original line number Original line Diff line number Diff line Loading @@ -4,11 +4,13 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SdkConstant.SdkConstantType; import android.app.Service; import android.app.Service; import android.content.Intent; import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.os.IBinder; import android.os.IBinder; import android.os.Message; import android.os.Message; import android.os.Messenger; import android.os.Messenger; import android.os.Parcel; import android.os.RemoteException; import android.os.RemoteException; import android.util.Log; import android.util.Log; Loading Loading @@ -97,6 +99,12 @@ public abstract class HostApduService extends Service { */ */ public static final int MSG_DEACTIVATED = 2; public static final int MSG_DEACTIVATED = 2; /** * * @hide */ public static final int MSG_UNHANDLED = 3; /** /** * @hide * @hide */ */ Loading @@ -105,6 +113,8 @@ public abstract class HostApduService extends Service { /** /** * Messenger interface to NfcService for sending responses. * Messenger interface to NfcService for sending responses. * Only accessed on main thread by the message handler. * Only accessed on main thread by the message handler. * * @hide */ */ Messenger mNfcService = null; Messenger mNfcService = null; Loading Loading @@ -133,6 +143,7 @@ public abstract class HostApduService extends Service { Bundle responseBundle = new Bundle(); Bundle responseBundle = new Bundle(); responseBundle.putByteArray(KEY_DATA, responseApdu); responseBundle.putByteArray(KEY_DATA, responseApdu); responseMsg.setData(responseBundle); responseMsg.setData(responseBundle); responseMsg.replyTo = mMessenger; try { try { mNfcService.send(responseMsg); mNfcService.send(responseMsg); } catch (RemoteException e) { } catch (RemoteException e) { Loading @@ -150,6 +161,7 @@ public abstract class HostApduService extends Service { return; return; } } try { try { msg.replyTo = mMessenger; mNfcService.send(msg); mNfcService.send(msg); } catch (RemoteException e) { } catch (RemoteException e) { Log.e(TAG, "RemoteException calling into NfcService."); Log.e(TAG, "RemoteException calling into NfcService."); Loading @@ -160,6 +172,18 @@ public abstract class HostApduService extends Service { mNfcService = null; mNfcService = null; onDeactivated(msg.arg1); onDeactivated(msg.arg1); break; 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: default: super.handleMessage(msg); super.handleMessage(msg); } } Loading Loading @@ -189,6 +213,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 * <p>This method will be called when a command APDU has been received * from a remote device. A response APDU can be provided directly * from a remote device. A response APDU can be provided directly Loading @@ -205,6 +287,7 @@ public abstract class HostApduService extends Service { * If you cannot return a response APDU immediately, return null * If you cannot return a response APDU immediately, return null * and use the {@link #sendResponseApdu(byte[])} method later. * and use the {@link #sendResponseApdu(byte[])} method later. * * * @deprecated use {@link #processCommandApdu(byte[], Bundle)} * @param commandApdu * @param commandApdu * @param flags * @param flags * @return a byte-array containing the response APDU, or null if no * @return a byte-array containing the response APDU, or null if no Loading