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

Commit 6f680a96 authored by yincheng zhao's avatar yincheng zhao
Browse files

Open an API for updating Fplmn

Bug: 78790236
Test: Tested via adb on blueline
Change-Id: I98e9b090421bb76258abade8e198528daccf7a3d
parent 3fc4039c
Loading
Loading
Loading
Loading
+97 −35
Original line number Original line Diff line number Diff line
@@ -94,6 +94,8 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
    static protected final int EVENT_READ_ICON_DONE = 10;
    static protected final int EVENT_READ_ICON_DONE = 10;
    /** Finished retrieving size of record for EFimg now. */
    /** Finished retrieving size of record for EFimg now. */
    static protected final int EVENT_GET_RECORD_SIZE_IMG_DONE = 11;
    static protected final int EVENT_GET_RECORD_SIZE_IMG_DONE = 11;
    /** Finished retriveing record size of transparent file. */
    protected static final int EVENT_GET_EF_TRANSPARENT_SIZE_DONE = 12;


     // member variables
     // member variables
    @UnsupportedAppUsage
    @UnsupportedAppUsage
@@ -222,14 +224,13 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
    }
    }


    /**
    /**
     * get record size for a linear fixed EF
     * Get record size for a linear fixed EF
     *
     *
     * @param fileid EF id
     * @param fileid EF id
     * @param path Path of the EF on the card
     * @param path Path of the EF on the card
     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the
     *        int[0] is the record length int[1] is the total length of the EF
     *     record length int[1] is the total length of the EF file int[3] is the number of records
     *        file int[3] is the number of records in the EF file So int[0] *
     *     in the EF file So int[0] * int[3] = int[1]
     *        int[3] = int[1]
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) {
    public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) {
@@ -242,19 +243,51 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
    }
    }


    /**
    /**
     * get record size for a linear fixed EF
     * Get record size for a linear fixed EF
     *
     *
     * @param fileid EF id
     * @param fileid EF id
     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[]
     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the
     *        int[0] is the record length int[1] is the total length of the EF
     *     record length int[1] is the total length of the EF file int[3] is the number of records
     *        file int[3] is the number of records in the EF file So int[0] *
     *     in the EF file So int[0] * int[3] = int[1]
     *        int[3] = int[1]
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void getEFLinearRecordSize(int fileid, Message onLoaded) {
    public void getEFLinearRecordSize(int fileid, Message onLoaded) {
        getEFLinearRecordSize(fileid, getEFPath(fileid), onLoaded);
        getEFLinearRecordSize(fileid, getEFPath(fileid), onLoaded);
    }
    }


    /**
     * Get record size for a transparent EF
     *
     * @param fileid EF id
     * @param path Path of the EF on the card
     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the size of data int
     */
    public void getEFTransparentRecordSize(int fileid, String path, Message onLoaded) {
        String efPath = (path == null) ? getEFPath(fileid) : path;
        Message response = obtainMessage(EVENT_GET_EF_TRANSPARENT_SIZE_DONE, fileid, 0, onLoaded);
        mCi.iccIOForApp(
                COMMAND_GET_RESPONSE,
                fileid,
                getEFPath(fileid),
                0,
                0,
                GET_RESPONSE_EF_SIZE_BYTES,
                null,
                null,
                mAid,
                response);
    }

    /**
     * Get record size for a transparent EF
     *
     * @param fileid EF id
     * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the size of the data int
     */
    public void getEFTransparentRecordSize(int fileid, Message onLoaded) {
        getEFTransparentRecordSize(fileid, getEFPath(fileid), onLoaded);
    }

    /**
    /**
     * Load all records from a SIM Linear Fixed EF
     * Load all records from a SIM Linear Fixed EF
     *
     *
@@ -263,7 +296,6 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
     * @param onLoaded
     * @param onLoaded
     *
     *
     * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
     * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]>
     *
     */
     */
    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) {
    public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) {
@@ -296,9 +328,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
     * @param onLoaded
     * @param onLoaded
     *
     *
     * ((AsyncResult)(onLoaded.obj)).result is the byte[]
     * ((AsyncResult)(onLoaded.obj)).result is the byte[]
     *
     */
     */

    @UnsupportedAppUsage
    @UnsupportedAppUsage
    public void loadEFTransparent(int fileid, Message onLoaded) {
    public void loadEFTransparent(int fileid, Message onLoaded) {
        Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
        Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
@@ -473,8 +503,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants {


                recordSize = new int[3];
                recordSize = new int[3];
                recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
                recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
                recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                recordSize[1] = getDataFileSize(data);
                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
                recordSize[2] = recordSize[1] / recordSize[0];
                recordSize[2] = recordSize[1] / recordSize[0];


                sendResult(response, recordSize, null);
                sendResult(response, recordSize, null);
@@ -505,8 +534,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants {


                lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;
                lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF;


                size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                size = getDataFileSize(data);
                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);


                lc.mCountRecords = size / lc.mRecordSize;
                lc.mCountRecords = size / lc.mRecordSize;


@@ -549,8 +577,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
                    throw new IccFileTypeMismatch();
                    throw new IccFileTypeMismatch();
                }
                }


                size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                size = getDataFileSize(data);
                       + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);


                mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
                mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
                                0, 0, size, null, null, mAid,
                                0, 0, size, null, null, mAid,
@@ -608,6 +635,31 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
                sendResult(response, result.payload, null);
                sendResult(response, result.payload, null);
            break;
            break;


            case EVENT_GET_EF_TRANSPARENT_SIZE_DONE:
                ar = (AsyncResult) msg.obj;
                response = (Message) ar.userObj;
                result = (IccIoResult) ar.result;

                if (processException(response, (AsyncResult) msg.obj)) {
                    break;
                }

                data = result.payload;

                fileid = msg.arg1;

                if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) {
                    throw new IccFileTypeMismatch();
                }

                if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) {
                    throw new IccFileTypeMismatch();
                }

                size = getDataFileSize(data);
                sendResult(response, size, null);
                break;

        }} catch (Exception exc) {
        }} catch (Exception exc) {
            if (response != null) {
            if (response != null) {
                sendResult(response, null, exc);
                sendResult(response, null, exc);
@@ -656,4 +708,14 @@ public abstract class IccFileHandler extends Handler implements IccConstants {
    protected abstract void logd(String s);
    protected abstract void logd(String s);
    protected abstract void loge(String s);
    protected abstract void loge(String s);


    /**
     * Calculate the size of a data file
     *
     * @param data the raw file
     * @return the size of the file
     */
    private static int getDataFileSize(byte[] data) {
        return (((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
                    + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff));
    }
}
}
+30 −12
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import android.telephony.Rlog;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Pair;


import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.MccTable;
@@ -181,8 +182,7 @@ public abstract class IccRecords extends Handler implements IccConstants {
    protected static final int HANDLER_ACTION_NONE = HANDLER_ACTION_BASE + 0;
    protected static final int HANDLER_ACTION_NONE = HANDLER_ACTION_BASE + 0;
    protected static final int HANDLER_ACTION_SEND_RESPONSE = HANDLER_ACTION_BASE + 1;
    protected static final int HANDLER_ACTION_SEND_RESPONSE = HANDLER_ACTION_BASE + 1;
    protected static AtomicInteger sNextRequestId = new AtomicInteger(1);
    protected static AtomicInteger sNextRequestId = new AtomicInteger(1);
    protected final HashMap<Integer, Message> mPendingResponses = new HashMap<>();
    protected final HashMap<Integer, Pair<Message, Object>> mPendingTransactions = new HashMap<>();

    // ***** Constants
    // ***** Constants


    // Markers for mncLength
    // Markers for mncLength
@@ -344,24 +344,42 @@ public abstract class IccRecords extends Handler implements IccConstants {
    }
    }


    /**
    /**
     * Adds a message to the pending requests list by generating a unique
     * Adds a message to the pending requests list by generating a unique (integer)
     * (integer) hash key and returning it. The message should never be null.
     * hash key and returning it. The message should never be null.
     *
     * @param msg Message of the transaction to be stored
     * @return the unique (integer) hash key to retrieve the pending transaction
     */
    public int storePendingTransaction(Message msg) {
        return storePendingTransaction(msg, null);
    }

    /**
     * Adds a message and obj pair to the pending requests list by generating a unique (integer)
     * hash key and returning it. The message should never be null.
     *
     * @param msg Message of the transaction to be stored
     * @param obj Object of the transaction to be stored
     * @return the unique (integer) hash key to retrieve the pending transaction
     */
     */
    public int storePendingResponseMessage(Message msg) {
    public int storePendingTransaction(Message msg, Object obj) {
        int key = sNextRequestId.getAndIncrement();
        int key = sNextRequestId.getAndIncrement();
        synchronized (mPendingResponses) {
        Pair<Message, Object> pair = new Pair<Message, Object>(msg, obj);
            mPendingResponses.put(key, msg);
        synchronized (mPendingTransactions) {
            mPendingTransactions.put(key, pair);
        }
        }
        return key;
        return key;
    }
    }


    /**
    /**
     * Returns the pending request, if any or null
     * Returns the pending transaction and free it from memory, if any or null
     *
     * @param key key of the entry to retrieve
     * @return The pending transaction.
     */
     */
    public Message retrievePendingResponseMessage(Integer key) {
    public Pair<Message, Object> retrievePendingTransaction(Integer key) {
        Message m;
        synchronized (mPendingTransactions) {
        synchronized (mPendingResponses) {
            return mPendingTransactions.remove(key);
            return mPendingResponses.remove(key);
        }
        }
    }
    }


+77 −3
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ import android.telephony.Rlog;
import android.telephony.SmsMessage;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionInfo;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.Pair;


import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.MccTable;
@@ -135,6 +136,10 @@ public class SIMRecords extends IccRecords {
    private static final int CFIS_ADN_CAPABILITY_ID_OFFSET = 14;
    private static final int CFIS_ADN_CAPABILITY_ID_OFFSET = 14;
    private static final int CFIS_ADN_EXTENSION_ID_OFFSET = 15;
    private static final int CFIS_ADN_EXTENSION_ID_OFFSET = 15;


    // 3GPP specification constants
    // Spec reference TS 31.102 section 4.2.16
    private static final int FPLMN_BYTE_SIZE = 3;

    // ***** Event Constants
    // ***** Event Constants
    private static final int SIM_RECORD_EVENT_BASE = 0x00;
    private static final int SIM_RECORD_EVENT_BASE = 0x00;
    private static final int EVENT_GET_IMSI_DONE = 3 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_IMSI_DONE = 3 + SIM_RECORD_EVENT_BASE;
@@ -169,7 +174,8 @@ public class SIMRecords extends IccRecords {
    private static final int EVENT_GET_HPLMN_W_ACT_DONE = 39 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_HPLMN_W_ACT_DONE = 39 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_EHPLMN_DONE = 40 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_EHPLMN_DONE = 40 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_FPLMN_DONE = 41 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_FPLMN_DONE = 41 + SIM_RECORD_EVENT_BASE;

    private static final int EVENT_GET_FPLMN_SIZE_DONE = 42 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_SET_FPLMN_DONE = 43 + SIM_RECORD_EVENT_BASE;
    // ***** Constructor
    // ***** Constructor


    public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
    public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
@@ -1194,7 +1200,8 @@ public class SIMRecords extends IccRecords {
                    if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) {
                    if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) {
                        if (VDBG) logv("getForbiddenPlmns(): send async response");
                        if (VDBG) logv("getForbiddenPlmns(): send async response");
                        isRecordLoadResponse = false;
                        isRecordLoadResponse = false;
                        Message response = retrievePendingResponseMessage(msg.arg2);
                        int key = msg.arg2;
                        Message response = retrievePendingTransaction(key).first;
                        if (response != null) {
                        if (response != null) {
                            AsyncResult.forMessage(
                            AsyncResult.forMessage(
                                    response, Arrays.copyOf(mFplmns, mFplmns.length), null);
                                    response, Arrays.copyOf(mFplmns, mFplmns.length), null);
@@ -1206,6 +1213,59 @@ public class SIMRecords extends IccRecords {
                    }
                    }
                    break;
                    break;


                case EVENT_GET_FPLMN_SIZE_DONE:
                    ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        Message response = (Message) ar.userObj;
                        AsyncResult.forMessage(response).exception = ar.exception;
                        response.sendToTarget();
                        break;
                    }
                    int key = msg.arg2;
                    Pair<Message, Object> transaction = retrievePendingTransaction(key);
                    Message response = transaction.first;
                    List<String> fplmns = (List<String>) transaction.second;
                    int dataLength = (int) ar.result;
                    if (dataLength < 0 || dataLength % FPLMN_BYTE_SIZE != 0) {
                        loge("Failed to retrieve a correct fplmn size: " + dataLength);
                        AsyncResult.forMessage(response, -1, null);
                        response.sendToTarget();
                        break;
                    }
                    int maxWritebaleFplmns = dataLength / FPLMN_BYTE_SIZE;
                    List<String> fplmnsToWrite;
                    if (fplmns.size() <= maxWritebaleFplmns) {
                        fplmnsToWrite = fplmns;
                    } else {
                        fplmnsToWrite = fplmns.subList(0, maxWritebaleFplmns);
                    }
                    key = storePendingTransaction(response, fplmnsToWrite);
                    byte[] encodededFplmns = IccUtils.encodeFplmns(fplmns, dataLength);
                    mFh.updateEFTransparent(
                            EF_FPLMN,
                            encodededFplmns,
                            obtainMessage(
                                    EVENT_SET_FPLMN_DONE,
                                    msg.arg1,
                                    key));
                    break;

                case EVENT_SET_FPLMN_DONE:
                    ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        loge("Failed setting Forbidden PLMNs: " + ar.exception);
                    } else {
                        transaction = retrievePendingTransaction(msg.arg2);
                        response = transaction.first;
                        mFplmns = ((List<String>) transaction.second).toArray(new String[0]);
                        if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) {
                            AsyncResult.forMessage(response, mFplmns.length, null);
                            response.sendToTarget();
                        }
                        log("Successfully setted fplmns " + ar.result);
                    }
                    break;

                default:
                default:
                    super.handleMessage(msg);   // IccRecords handles generic record load responses
                    super.handleMessage(msg);   // IccRecords handles generic record load responses
            }
            }
@@ -1457,11 +1517,25 @@ public class SIMRecords extends IccRecords {
     * in the result field of an AsyncResult in the response.obj.
     * in the result field of an AsyncResult in the response.obj.
     */
     */
    public void getForbiddenPlmns(Message response) {
    public void getForbiddenPlmns(Message response) {
        int key = storePendingResponseMessage(response);
        int key = storePendingTransaction(response);
        mFh.loadEFTransparent(EF_FPLMN, obtainMessage(
        mFh.loadEFTransparent(EF_FPLMN, obtainMessage(
                    EVENT_GET_FPLMN_DONE, HANDLER_ACTION_SEND_RESPONSE, key));
                    EVENT_GET_FPLMN_DONE, HANDLER_ACTION_SEND_RESPONSE, key));
    }
    }


    /**
     * Set the forbidden PLMNs on the sim
     *
     * @param response Response to be send back.
     * @param fplmns List of fplmns to be written to SIM.
     */
    public void setForbiddenPlmns(Message response, List<String> fplmns) {
        int key = storePendingTransaction(response, fplmns);
        mFh.getEFTransparentRecordSize(
                EF_FPLMN,
                obtainMessage(EVENT_GET_FPLMN_SIZE_DONE, HANDLER_ACTION_SEND_RESPONSE, key));
    }


    @Override
    @Override
    public void onReady() {
    public void onReady() {
        fetchSimRecords();
        fetchSimRecords();