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

Commit a1a4b4ab authored by Roshan Pius's avatar Roshan Pius
Browse files

nfc(api): Copy over utilities used by non-mainline API classes

Classes like AidGroup will not be part of NFC mainline module, so it
should not be accessing utility @hide methods from classes which are
part of mainline module.

Bug: 303286040
Test: Compiles
Change-Id: I5ab7d48c121b27f442c1e72687e0b24d994e1138
parent f8ced8b7
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

/**********************************************************************
 * This file is not a part of the NFC mainline module                 *
@@ -79,7 +80,7 @@ public final class AidGroup implements Parcelable {
            throw new IllegalArgumentException("Too many AIDs in AID group.");
        }
        for (String aid : aids) {
            if (!CardEmulation.isValidAid(aid)) {
            if (!isValidAid(aid)) {
                throw new IllegalArgumentException("AID " + aid + " is not a valid AID.");
            }
        }
@@ -264,4 +265,34 @@ public final class AidGroup implements Parcelable {
        return CardEmulation.CATEGORY_PAYMENT.equals(category) ||
                CardEmulation.CATEGORY_OTHER.equals(category);
    }

    private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
    /**
     * Copied over from {@link CardEmulation#isValidAid(String)}
     * @hide
     */
    private static boolean isValidAid(String aid) {
        if (aid == null)
            return false;

        // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*')
        if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) {
            Log.e(TAG, "AID " + aid + " is not a valid AID.");
            return false;
        }

        // If not a prefix/subset AID, the total length must be even (even # of AID chars)
        if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) {
            Log.e(TAG, "AID " + aid + " is not a valid AID.");
            return false;
        }

        // Verify hex characters
        if (!AID_PATTERN.matcher(aid).matches()) {
            Log.e(TAG, "AID " + aid + " is not a valid AID.");
            return false;
        }

        return true;
    }
}
+35 −4
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Class holding APDU service info.
@@ -307,7 +308,7 @@ public final class ApduServiceInfo implements Parcelable {
                            com.android.internal.R.styleable.AidFilter);
                    String aid = a.getString(com.android.internal.R.styleable.AidFilter_name).
                            toUpperCase();
                    if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
                    if (isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
                        currentGroup.getAids().add(aid);
                    } else {
                        Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
@@ -321,7 +322,7 @@ public final class ApduServiceInfo implements Parcelable {
                            toUpperCase();
                    // Add wildcard char to indicate prefix
                    aid = aid.concat("*");
                    if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
                    if (isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
                        currentGroup.getAids().add(aid);
                    } else {
                        Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
@@ -335,7 +336,7 @@ public final class ApduServiceInfo implements Parcelable {
                            toUpperCase();
                    // Add wildcard char to indicate suffix
                    aid = aid.concat("#");
                    if (CardEmulation.isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
                    if (isValidAid(aid) && !currentGroup.getAids().contains(aid)) {
                        currentGroup.getAids().add(aid);
                    } else {
                        Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid);
@@ -806,7 +807,7 @@ public final class ApduServiceInfo implements Parcelable {
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
    public void dumpDebug(@NonNull ProtoOutputStream proto) {
        Utils.dumpDebugComponentName(getComponent(), proto, ApduServiceInfoProto.COMPONENT_NAME);
        getComponent().dumpDebug(proto, ApduServiceInfoProto.COMPONENT_NAME);
        proto.write(ApduServiceInfoProto.DESCRIPTION, getDescription());
        proto.write(ApduServiceInfoProto.ON_HOST, mOnHost);
        if (!mOnHost) {
@@ -825,4 +826,34 @@ public final class ApduServiceInfo implements Parcelable {
        }
        proto.write(ApduServiceInfoProto.SETTINGS_ACTIVITY_NAME, mSettingsActivityName);
    }

    private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?");
    /**
     * Copied over from {@link CardEmulation#isValidAid(String)}
     * @hide
     */
    private static boolean isValidAid(String aid) {
        if (aid == null)
            return false;

        // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*')
        if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) {
            Log.e(TAG, "AID " + aid + " is not a valid AID.");
            return false;
        }

        // If not a prefix/subset AID, the total length must be even (even # of AID chars)
        if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) {
            Log.e(TAG, "AID " + aid + " is not a valid AID.");
            return false;
        }

        // Verify hex characters
        if (!AID_PATTERN.matcher(aid).matches()) {
            Log.e(TAG, "AID " + aid + " is not a valid AID.");
            return false;
        }

        return true;
    }
}
+55 −3
Original line number Diff line number Diff line
@@ -173,7 +173,7 @@ public final class NfcFServiceInfo implements Parcelable {
                            com.android.internal.R.styleable.SystemCodeFilter);
                    systemCode = a.getString(
                            com.android.internal.R.styleable.SystemCodeFilter_name).toUpperCase();
                    if (!NfcFCardEmulation.isValidSystemCode(systemCode) &&
                    if (!isValidSystemCode(systemCode) &&
                            !systemCode.equalsIgnoreCase("NULL")) {
                        Log.e(TAG, "Invalid System Code: " + systemCode);
                        systemCode = null;
@@ -187,7 +187,7 @@ public final class NfcFServiceInfo implements Parcelable {
                            com.android.internal.R.styleable.Nfcid2Filter_name).toUpperCase();
                    if (!nfcid2.equalsIgnoreCase("RANDOM") &&
                            !nfcid2.equalsIgnoreCase("NULL") &&
                            !NfcFCardEmulation.isValidNfcid2(nfcid2)) {
                            !isValidNfcid2(nfcid2)) {
                        Log.e(TAG, "Invalid NFCID2: " + nfcid2);
                        nfcid2 = null;
                    }
@@ -436,10 +436,62 @@ public final class NfcFServiceInfo implements Parcelable {
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE)
    public void dumpDebug(@NonNull ProtoOutputStream proto) {
        Utils.dumpDebugComponentName(getComponent(), proto, NfcFServiceInfoProto.COMPONENT_NAME);
        getComponent().dumpDebug(proto, NfcFServiceInfoProto.COMPONENT_NAME);
        proto.write(NfcFServiceInfoProto.DESCRIPTION, getDescription());
        proto.write(NfcFServiceInfoProto.SYSTEM_CODE, getSystemCode());
        proto.write(NfcFServiceInfoProto.NFCID2, getNfcid2());
        proto.write(NfcFServiceInfoProto.T3T_PMM, getT3tPmm());
    }

    /**
     * Copied over from {@link NfcFCardEmulation#isValidSystemCode(String)}
     * @hide
     */
    private static boolean isValidSystemCode(String systemCode) {
        if (systemCode == null) {
            return false;
        }
        if (systemCode.length() != 4) {
            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
            return false;
        }
        // check if the value is between "4000" and "4FFF" (excluding "4*FF")
        if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) {
            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
            return false;
        }
        try {
            Integer.parseInt(systemCode, 16);
        } catch (NumberFormatException e) {
            Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
            return false;
        }
        return true;
    }

    /**
     * Copied over from {@link NfcFCardEmulation#isValidNfcid2(String)}
     * @hide
     */
    private static boolean isValidNfcid2(String nfcid2) {
        if (nfcid2 == null) {
            return false;
        }
        if (nfcid2.length() != 16) {
            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
            return false;
        }
        // check if the the value starts with "02FE"
        if (!nfcid2.toUpperCase().startsWith("02FE")) {
            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
            return false;
        }
        try {
            Long.parseLong(nfcid2, 16);
        } catch (NumberFormatException e) {
            Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
            return false;
        }
        return true;
    }
}