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

Commit 8bae2625 authored by Junho Yoon's avatar Junho Yoon Committed by Android (Google) Code Review
Browse files

Merge "Fetch EF-UICCIARI from UICC" into main

parents 7bb08674 583ac861
Loading
Loading
Loading
Loading
+81 −0
Original line number Diff line number Diff line
@@ -32,13 +32,17 @@ import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.TelephonyServiceManager.ServiceRegisterer;
import android.telephony.ImsiEncryptionInfo;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.EventLog;

@@ -54,6 +58,7 @@ import com.android.telephony.Rlog;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@@ -673,6 +678,82 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
                });
    }

    /**
     * Fetches the IMS Application Reference Identifier(IARI) based on the subscription.
     *
     * @param subId subscriptionId
     * @param appType the uicc app type
     * @param callingPackage package name of the caller
     * @param callback result receiver to get the iist of IARI strings. The result code is ignored.
     */
    public void getUiccIari(int subId, int appType, String callingPackage,
            ResultReceiver callback) {
        if (!mFeatureFlags.supportImsRegistrationEventDownload()) {
            callbackUiccIari(callback, new ArrayList<>(), null);
            return;
        }
        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
            callbackUiccIari(callback, null,
                    new IllegalArgumentException("Invalid subscription: " + subId));
            return;
        }
        try {
            TelephonyPermissions
                    .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
                            mContext, subId, "getUiccIari");
            enforceTelephonyFeatureWithException(callingPackage,
                    PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccIari");
        } catch (SecurityException | UnsupportedOperationException ex) {
            callbackUiccIari(callback, null, ex);
            return;
        }

        Phone phone = getPhone(subId);
        if (phone == null) {
            loge("getUiccIari(): phone is null");
            callbackUiccIari(callback, Collections.emptyList(), null);
            return;
        }
        UiccPort uiccPort = phone.getUiccPort();
        if (uiccPort == null || uiccPort.getUiccProfile() == null) {
            loge("getUiccIari(): uiccPort or uiccProfile is null");
            callbackUiccIari(callback, Collections.emptyList(), null);
            return;
        }
        UiccCardApplication uiccApp = uiccPort.getUiccProfile().getApplicationByType(appType);
        if (uiccApp == null) {
            loge("getUiccIari(): no app with specified apptype=" + appType);
            callbackUiccIari(callback, Collections.emptyList(), null);
            return;
        }

        String[] iaris = uiccApp.getIccRecords().getUiccIari();
        if (iaris == null) {
            loge("getUiccIari(): IARI list is null");
            callbackUiccIari(callback, Collections.emptyList(), null);
            return;
        }
        List<String> iariList = Arrays.stream(iaris)
                .filter(u -> u != null)
                .map(u -> u.trim())
                .filter(u -> u.length() > 0)
                .collect(Collectors.toList());
        callbackUiccIari(callback, iariList, null);
    }

    private void callbackUiccIari(ResultReceiver callback, List<String> iari, Exception ex) {
        Bundle result = new Bundle();
        if (ex != null) {
            result.putParcelable(TelephonyManager.KEY_UICC_IARI_EXCEPTION,
                    new ParcelableException(ex));
        } else {
            result.putStringArrayList(TelephonyManager.KEY_UICC_IARI_LIST,
                    (iari == null)
                            ? new ArrayList<>(Collections.emptyList()) : new ArrayList<>(iari));
        }
        callback.send(0, result);
    }

    /** Below are utility methods that abstracts the flow that many public methods use:
     *  1. Check permission: pass, throw exception, or fails (returns false).
     *  2. clearCallingIdentity.
+3 −0
Original line number Diff line number Diff line
@@ -102,6 +102,9 @@ public interface IccConstants {
    //Search interval for higher priority PLMNs
    static final int EF_HPPLMN = 0x6F31;

    // IMS Application Reference Identifier in TS 131.102 and TS131.103
    int EF_IARI = 0x6FE7;

    static final String MF_SIM = "3F00";
    static final String DF_TELECOM = "7F10";
    static final String DF_PHONEBOOK = "5F3A";
+8 −0
Original line number Diff line number Diff line
@@ -1253,6 +1253,14 @@ public abstract class IccRecords extends Handler implements IccConstants {
        return null;
    }

    /**
     * Returns the IMS Application Reference Identifier(IARI).
     * @return array of IARI or null if not presend
     */
    public String[] getUiccIari() {
        return null;
    }

    /**
     * Solve authentication leakage issue. See b/147463955.
     * Returns the response of the SIM application on the UICC to authentication
+41 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
    private String mIsimIst;                // IMS Service Table
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private String[] mIsimPcscf;            // IMS Proxy Call Session Control Function
    private String[] mIsimIari;             // IMS Application Reference Identifier
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private String auth_rsp;

@@ -82,6 +83,7 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
                + " mIsimIst=" + mIsimIst
                + " mIsimPcscf=" + Arrays.toString(mIsimPcscf)
                + " mPsiSmsc=" + mPsiSmsc
                + " mIsimIari=" + Arrays.toString(mIsimIari)
                + " mSmss TPMR=" + getSmssTpmrValue()) : "");
    }

@@ -164,6 +166,10 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimPsiSmscLoaded()));
        mRecordsToLoad++;

        mFh.loadEFLinearFixedAll(EF_IARI, obtainMessage(
                IccRecords.EVENT_GET_ICC_RECORD_DONE, new EfIsimIariLoaded()));
        mRecordsToLoad++;

        if (DBG) log("fetchIsimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
    }

@@ -177,6 +183,7 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
        mIsimIst = null;
        mIsimPcscf = null;
        auth_rsp = null;
        mIsimIari = null;

        mRecordsRequested = false;
        mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE;
@@ -290,6 +297,30 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
        }
    }

    @VisibleForTesting
    public EfIsimIariLoaded getIsimIariObject() {
        return new EfIsimIariLoaded();
    }

    private class EfIsimIariLoaded implements IccRecords.IccRecordLoaded {
        public String getEfName() {
            return "EF_ISIM_IARI";
        }
        public void onRecordLoaded(AsyncResult ar) {
            ArrayList<byte[]> iariList = (ArrayList<byte[]>) ar.result;
            if (iariList != null && iariList.size() > 0) {
                if (DBG) log("EF_IARI record count: " + iariList.size());
                mIsimIari = new String[iariList.size()];
                int i = 0;
                for (byte[] data : iariList) {
                    String iari = isimTlvToString(data);
                    if (DUMP_RECORDS) log("EF_IARI[" + i + "]=" + iari);
                    mIsimIari[i++] = iari;
                }
            }
        }
    }

    @VisibleForTesting
    public EfIsimPsiSmscLoaded getPsiSmscObject() {
        return new EfIsimPsiSmscLoaded();
@@ -473,6 +504,15 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
        // Not applicable to Isim
    }

    /**
     * Returns the IMS Application Reference Identifier(IARI) that was loaded from the ISIM.
     * @return array of IARI or null if not loaded
     */
    @Override
    public String[] getUiccIari() {
        return (mIsimIari != null) ? mIsimIari.clone() : null;
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    @Override
    protected void log(String s) {
@@ -504,6 +544,7 @@ public class IsimUiccRecords extends IccRecords implements IsimRecords {
            pw.println(" mIsimImpu[]=" + Arrays.toString(mIsimImpu));
            pw.println(" mIsimPcscf" + Arrays.toString(mIsimPcscf));
            pw.println(" mPsismsc=" + mPsiSmsc);
            pw.println(" mIsimIari" + Arrays.toString(mIsimIari));
            pw.println(" mSmss TPMR=" + getSmssTpmrValue());
        }
        pw.flush();
+54 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -101,6 +102,8 @@ public class SIMRecords extends IccRecords {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    UsimServiceTable mUsimServiceTable;

    private String[] mUsimIari;    // IMS Application Reference Identifier

    @Override
    public String toString() {
        return "SimRecords: " + super.toString()
@@ -115,6 +118,7 @@ public class SIMRecords extends IccRecords {
                + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis)
                + " getOperatorNumeric=" + getOperatorNumeric()
                + " mPsiSmsc=" + mPsiSmsc
                + " mUsimIari=" + Arrays.toString(mUsimIari)
                + " TPMR=" + getSmssTpmrValue();
    }

@@ -133,6 +137,9 @@ public class SIMRecords extends IccRecords {
    // PLMN Additional Information tag from from TS 24.008
    static final int TAG_PLMN_ADDITIONAL_INFORMATION = 0x80;

    // IARI TLV TAG from TS 31.102
    static final int TAG_IARI_TLV = 0x80;

    // active CFF from CPHS 4.2 B.4.5
    static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
    static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
@@ -193,6 +200,7 @@ public class SIMRecords extends IccRecords {
    private static final int EVENT_SET_FPLMN_DONE = 43 + SIM_RECORD_EVENT_BASE;
    protected static final int EVENT_GET_SMSS_RECORD_DONE = 46 + SIM_RECORD_EVENT_BASE;
    protected static final int EVENT_GET_PSISMSC_DONE = 47 + SIM_RECORD_EVENT_BASE;
    protected static final int EVENT_GET_IARI_DONE = 48 + SIM_RECORD_EVENT_BASE;

    // ***** Constructor

@@ -252,6 +260,7 @@ public class SIMRecords extends IccRecords {
        mHplmnActRecords = null;
        mFplmns = null;
        mEhplmns = null;
        mUsimIari = null;

        mAdnCache.reset();

@@ -282,6 +291,15 @@ public class SIMRecords extends IccRecords {
        return mUsimServiceTable;
    }

    /**
     * Returns the IMS Application Reference Identifier(IARI) that was loaded from the USIM.
     * @return array of IARI or null if not loaded
     */
    @Override
    public String[] getUiccIari() {
        return (mUsimIari != null) ? mUsimIari.clone() : null;
    }

    /**
     * Fetches the USIM service table from UsimServiceTable
     *
@@ -1368,6 +1386,19 @@ public class SIMRecords extends IccRecords {
                    }
                    break;

                case EVENT_GET_IARI_DONE:
                    isRecordLoadResponse = true;
                    ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        loge("Failed to read USIM EF_IARI field error=" + ar.exception);
                    } else {
                        List<byte[]> iariList = (List<byte[]>) ar.result;
                        if (iariList != null && iariList.size() > 0) {
                            parseEfIari(iariList);
                        }
                    }
                    break;

                default:
                    super.handleMessage(msg);   // IccRecords handles generic record load responses
            }
@@ -1769,6 +1800,9 @@ public class SIMRecords extends IccRecords {
        mFh.loadEFTransparent(EF_SMSS, obtainMessage(EVENT_GET_SMSS_RECORD_DONE));
        mRecordsToLoad++;

        mFh.loadEFLinearFixedAll(EF_IARI, obtainMessage(EVENT_GET_IARI_DONE));
        mRecordsToLoad++;

        if (CRASH_RIL) {
            String sms = "0107912160130310f20404d0110041007030208054832b0120"
                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
@@ -2097,6 +2131,25 @@ public class SIMRecords extends IccRecords {
        return ret;
    }

    /**
     * convert a byte array of packed IARIs to an array of strings
     * Reference: 3GPP TS 31.102 Section 4.2.95 and TS 31.103 Section 4.2.16.
     */
    private void parseEfIari(List<byte[]> dataList) {
        final int count = dataList.size();
        mUsimIari = new String[count];
        for (int i = 0; i < count; i++) {
            byte[] data = dataList.get(i);
            SimTlv tlv = new SimTlv(data, 0, data.length);
            if (tlv.getTag() == TAG_IARI_TLV) {
                mUsimIari[i] = new String(tlv.getData(), StandardCharsets.UTF_8);
            } else {
                mUsimIari[i] = null;
            }
        }
        if (VDBG) logv("IARIs: " + Arrays.toString(mUsimIari));
    }

    /**
     * check to see if Mailbox Number is allocated and activated in CPHS SST
     */
@@ -2233,6 +2286,7 @@ public class SIMRecords extends IccRecords {
        pw.println(" mFplmns[]=" + Arrays.toString(mFplmns));
        pw.println(" mEhplmns[]=" + Arrays.toString(mEhplmns));
        pw.println(" mPsismsc=" + mPsiSmsc);
        pw.println(" mUsimIari=" + Arrays.toString(mUsimIari));
        pw.println(" TPMR=" + getSmssTpmrValue());
        pw.flush();
    }
Loading