Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b6e89439 authored by Martijn Coenen's avatar Martijn Coenen Committed by Android (Google) Code Review
Browse files

Merge "NFC: Allow HostApduService to indicate transaction unhandled." into klp-dev

parents 6b73eb28 583fe9d2
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -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
+83 −0
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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
     */
     */
@@ -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;


@@ -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) {
@@ -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.");
@@ -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);
            }
            }
@@ -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
@@ -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