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

Commit 54502d68 authored by Ruchi Kandoi's avatar Ruchi Kandoi Committed by Gerrit Code Review
Browse files

Merge changes from topic "multi-se-support"

* changes:
  Add a mechanism to register AIDs to specific off-host SE
  Add Off-Host Card Emulation Features
parents cdf6be57 44bb5796
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -11317,6 +11317,8 @@ package android.content.pm {
    field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
    field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
    field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
    field public static final java.lang.String FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE = "android.hardware.nfc.ese";
    field public static final java.lang.String FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC = "android.hardware.nfc.uicc";
    field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
    field public static final java.lang.String FEATURE_PC = "android.hardware.type.pc";
    field public static final java.lang.String FEATURE_PICTURE_IN_PICTURE = "android.software.picture_in_picture";
@@ -29165,6 +29167,7 @@ package android.nfc {
    method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
    method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
    method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
    method public java.util.List<java.lang.String> getSupportedOffHostSecureElements();
    method public boolean ignore(android.nfc.Tag, int, android.nfc.NfcAdapter.OnTagRemovedListener, android.os.Handler);
    method public boolean invokeBeam(android.app.Activity);
    method public boolean isEnabled();
@@ -29256,8 +29259,10 @@ package android.nfc.cardemulation {
    method public boolean isDefaultServiceForCategory(android.content.ComponentName, java.lang.String);
    method public boolean registerAidsForService(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>);
    method public boolean removeAidsForService(android.content.ComponentName, java.lang.String);
    method public boolean setOffHostForService(android.content.ComponentName, java.lang.String);
    method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
    method public boolean supportsAidPrefixRegistration();
    method public boolean unsetOffHostForService(android.content.ComponentName);
    method public boolean unsetPreferredService(android.app.Activity);
    field public static final java.lang.String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
    field public static final java.lang.String CATEGORY_OTHER = "other";
+17 −0
Original line number Diff line number Diff line
@@ -1912,6 +1912,23 @@ public abstract class PackageManager {
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports uicc-
     * based NFC card emulation.
     */
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC =
                                                                       "android.hardware.nfc.uicc";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports eSE-
     * based NFC card emulation.
     */
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE = "android.hardware.nfc.ese";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports any
+2 −0
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ interface INfcCardEmulation
    boolean setDefaultServiceForCategory(int userHandle, in ComponentName service, String category);
    boolean setDefaultForNextTap(int userHandle, in ComponentName service);
    boolean registerAidGroupForService(int userHandle, in ComponentName service, in AidGroup aidGroup);
    boolean setOffHostForService(int userHandle, in ComponentName service, in String offHostSecureElement);
    boolean unsetOffHostForService(int userHandle, in ComponentName service);
    AidGroup getAidGroupForService(int userHandle, in ComponentName service, String category);
    boolean removeAidGroupForService(int userHandle, in ComponentName service, String category);
    List<ApduServiceInfo> getServices(int userHandle, in String category);
+32 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.nfc;

import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
@@ -42,7 +43,9 @@ import android.os.ServiceManager;
import android.util.Log;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Represents the local NFC adapter.
@@ -487,6 +490,35 @@ public final class NfcAdapter {
        }
    }

    /**
     * Return list of Secure Elements which support off host card emulation.
     *
     * @return List<String> containing secure elements on the device which supports
     *                      off host card emulation. eSE for Embedded secure element,
     *                      SIM for UICC and so on.
     */
    public @NonNull List<String> getSupportedOffHostSecureElements() {
        List<String> offHostSE = new ArrayList<String>();
        IPackageManager pm = ActivityThread.getPackageManager();
        if (pm == null) {
            Log.e(TAG, "Cannot get package manager, assuming no off-host CE feature");
            return offHostSE;
        }
        try {
            if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC, 0)) {
                offHostSE.add("SIM");
            }
            if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE, 0)) {
                offHostSE.add("eSE");
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Package manager query failed, assuming no off-host CE feature", e);
            offHostSE.clear();
            return offHostSE;
        }
        return offHostSE;
    }

    /**
     * Returns the NfcAdapter for application context,
     * or throws if NFC is not available.
+62 −8
Original line number Diff line number Diff line
@@ -18,11 +18,10 @@ package android.nfc.cardemulation;

import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.TypedArray;
@@ -30,7 +29,6 @@ import android.content.res.XmlResourceParser;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ResultReceiver;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -68,6 +66,18 @@ public final class ApduServiceInfo implements Parcelable {
     */
    final boolean mOnHost;

    /**
     * Offhost reader name.
     * eg: SIM, eSE etc
     */
    String mOffHostName;

    /**
     * Offhost reader name from manifest file.
     * Used for unsetOffHostSecureElement()
     */
    final String mStaticOffHostName;

    /**
     * Mapping from category to static AID group
     */
@@ -104,15 +114,17 @@ public final class ApduServiceInfo implements Parcelable {
     * @hide
     */
    @UnsupportedAppUsage
    public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
    public ApduServiceInfo(ResolveInfo info, String description,
            ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
            boolean requiresUnlock, int bannerResource, int uid,
            String settingsActivityName) {
            String settingsActivityName, String offHost, String staticOffHost) {
        this.mService = info;
        this.mDescription = description;
        this.mStaticAidGroups = new HashMap<String, AidGroup>();
        this.mDynamicAidGroups = new HashMap<String, AidGroup>();
        this.mOnHost = onHost;
        this.mOffHostName = offHost;
        this.mStaticOffHostName = staticOffHost;
        this.mOnHost = (offHost == null);
        this.mRequiresDeviceUnlock = requiresUnlock;
        for (AidGroup aidGroup : staticAidGroups) {
            this.mStaticAidGroups.put(aidGroup.category, aidGroup);
@@ -174,6 +186,8 @@ public final class ApduServiceInfo implements Parcelable {
                        com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1);
                mSettingsActivityName = sa.getString(
                        com.android.internal.R.styleable.HostApduService_settingsActivity);
                mOffHostName = null;
                mStaticOffHostName = mOffHostName;
                sa.recycle();
            } else {
                TypedArray sa = res.obtainAttributes(attrs,
@@ -186,6 +200,16 @@ public final class ApduServiceInfo implements Parcelable {
                        com.android.internal.R.styleable.OffHostApduService_apduServiceBanner, -1);
                mSettingsActivityName = sa.getString(
                        com.android.internal.R.styleable.HostApduService_settingsActivity);
                mOffHostName = sa.getString(
                        com.android.internal.R.styleable.OffHostApduService_secureElementName);
                if (mOffHostName != null) {
                    if (mOffHostName.equals("eSE")) {
                        mOffHostName = "eSE1";
                    } else if (mOffHostName.equals("SIM")) {
                        mOffHostName = "SIM1";
                    }
                }
                mStaticOffHostName = mOffHostName;
                sa.recycle();
            }

@@ -289,6 +313,10 @@ public final class ApduServiceInfo implements Parcelable {
                mService.serviceInfo.name);
    }

    public String getOffHostSecureElement() {
        return mOffHostName;
    }

    /**
     * Returns a consolidated list of AIDs from the AID groups
     * registered by this service. Note that if a service has both
@@ -404,6 +432,20 @@ public final class ApduServiceInfo implements Parcelable {
        mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup);
    }

    @UnsupportedAppUsage
    public void setOffHostSecureElement(String offHost) {
        mOffHostName = offHost;
    }

    /**
     * Resets the off host Secure Element to statically defined
     * by the service in the manifest file.
     */
    @UnsupportedAppUsage
    public void unsetOffHostSecureElement() {
        mOffHostName = mStaticOffHostName;
    }

    public CharSequence loadLabel(PackageManager pm) {
        return mService.loadLabel(pm);
    }
@@ -481,6 +523,8 @@ public final class ApduServiceInfo implements Parcelable {
        mService.writeToParcel(dest, flags);
        dest.writeString(mDescription);
        dest.writeInt(mOnHost ? 1 : 0);
        dest.writeString(mOffHostName);
        dest.writeString(mStaticOffHostName);
        dest.writeInt(mStaticAidGroups.size());
        if (mStaticAidGroups.size() > 0) {
            dest.writeTypedList(new ArrayList<AidGroup>(mStaticAidGroups.values()));
@@ -503,6 +547,8 @@ public final class ApduServiceInfo implements Parcelable {
            ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
            String description = source.readString();
            boolean onHost = source.readInt() != 0;
            String offHostName = source.readString();
            String staticOffHostName = source.readString();
            ArrayList<AidGroup> staticAidGroups = new ArrayList<AidGroup>();
            int numStaticGroups = source.readInt();
            if (numStaticGroups > 0) {
@@ -517,9 +563,9 @@ public final class ApduServiceInfo implements Parcelable {
            int bannerResource = source.readInt();
            int uid = source.readInt();
            String settingsActivityName = source.readString();
            return new ApduServiceInfo(info, onHost, description, staticAidGroups,
            return new ApduServiceInfo(info, description, staticAidGroups,
                    dynamicAidGroups, requiresUnlock, bannerResource, uid,
                    settingsActivityName);
                    settingsActivityName, offHostName, staticOffHostName);
        }

        @Override
@@ -531,6 +577,14 @@ public final class ApduServiceInfo implements Parcelable {
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("    " + getComponent() +
                " (Description: " + getDescription() + ")");
        if (mOnHost) {
            pw.println("    On Host Service");
        } else {
            pw.println("    Off-host Service");
            pw.println("        " + "Current off-host SE" + mOffHostName
                    + " static off-host: " + mOffHostName);
        }
        pw.println("    Static off-host Secure Element:");
        pw.println("    Static AID groups:");
        for (AidGroup group : mStaticAidGroups.values()) {
            pw.println("        Category: " + group.category);
Loading