Loading src/java/com/android/internal/telephony/uicc/IccFileHandler.java +97 −35 Original line number Diff line number Diff line Loading @@ -94,6 +94,8 @@ public abstract class IccFileHandler extends Handler implements IccConstants { static protected final int EVENT_READ_ICON_DONE = 10; /** Finished retrieving size of record for EFimg now. */ 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 @UnsupportedAppUsage Loading Loading @@ -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 path Path of the EF on the card * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] * int[0] is the record length int[1] is the total length of the EF * file int[3] is the number of records in the EF file So int[0] * * int[3] = int[1] * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the * record length int[1] is the total length of the EF file int[3] is the number of records * in the EF file So int[0] * int[3] = int[1] */ @UnsupportedAppUsage public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) { Loading @@ -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 onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] * int[0] is the record length int[1] is the total length of the EF * file int[3] is the number of records in the EF file So int[0] * * int[3] = int[1] * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the * record length int[1] is the total length of the EF file int[3] is the number of records * in the EF file So int[0] * int[3] = int[1] */ @UnsupportedAppUsage public void getEFLinearRecordSize(int fileid, Message 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 * Loading @@ -263,7 +296,6 @@ public abstract class IccFileHandler extends Handler implements IccConstants { * @param onLoaded * * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]> * */ @UnsupportedAppUsage public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) { Loading Loading @@ -296,9 +328,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { * @param onLoaded * * ((AsyncResult)(onLoaded.obj)).result is the byte[] * */ @UnsupportedAppUsage public void loadEFTransparent(int fileid, Message onLoaded) { Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE, Loading Loading @@ -473,8 +503,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { recordSize = new int[3]; recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); recordSize[1] = getDataFileSize(data); recordSize[2] = recordSize[1] / recordSize[0]; sendResult(response, recordSize, null); Loading Loading @@ -505,8 +534,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); size = getDataFileSize(data); lc.mCountRecords = size / lc.mRecordSize; Loading Loading @@ -549,8 +577,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { throw new IccFileTypeMismatch(); } size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); size = getDataFileSize(data); mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid), 0, 0, size, null, null, mAid, Loading Loading @@ -608,6 +635,31 @@ public abstract class IccFileHandler extends Handler implements IccConstants { sendResult(response, result.payload, null); 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) { if (response != null) { sendResult(response, null, exc); Loading Loading @@ -656,4 +708,14 @@ public abstract class IccFileHandler extends Handler implements IccConstants { protected abstract void logd(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)); } } src/java/com/android/internal/telephony/uicc/IccRecords.java +30 −12 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.telephony.Rlog; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Pair; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.MccTable; Loading Loading @@ -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_SEND_RESPONSE = HANDLER_ACTION_BASE + 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 // Markers for mncLength Loading Loading @@ -344,24 +344,42 @@ public abstract class IccRecords extends Handler implements IccConstants { } /** * Adds a message to the pending requests list by generating a unique * (integer) hash key and returning it. The message should never be null. * Adds a message 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 * @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(); synchronized (mPendingResponses) { mPendingResponses.put(key, msg); Pair<Message, Object> pair = new Pair<Message, Object>(msg, obj); synchronized (mPendingTransactions) { mPendingTransactions.put(key, pair); } 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) { Message m; synchronized (mPendingResponses) { return mPendingResponses.remove(key); public Pair<Message, Object> retrievePendingTransaction(Integer key) { synchronized (mPendingTransactions) { return mPendingTransactions.remove(key); } } Loading src/java/com/android/internal/telephony/uicc/SIMRecords.java +77 −3 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.telephony.Rlog; import android.telephony.SmsMessage; import android.telephony.SubscriptionInfo; import android.text.TextUtils; import android.util.Pair; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.MccTable; Loading Loading @@ -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_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 private static final int SIM_RECORD_EVENT_BASE = 0x00; private static final int EVENT_GET_IMSI_DONE = 3 + SIM_RECORD_EVENT_BASE; Loading Loading @@ -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_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_SIZE_DONE = 42 + SIM_RECORD_EVENT_BASE; private static final int EVENT_SET_FPLMN_DONE = 43 + SIM_RECORD_EVENT_BASE; // ***** Constructor public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) { Loading Loading @@ -1194,7 +1200,8 @@ public class SIMRecords extends IccRecords { if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) { if (VDBG) logv("getForbiddenPlmns(): send async response"); isRecordLoadResponse = false; Message response = retrievePendingResponseMessage(msg.arg2); int key = msg.arg2; Message response = retrievePendingTransaction(key).first; if (response != null) { AsyncResult.forMessage( response, Arrays.copyOf(mFplmns, mFplmns.length), null); Loading @@ -1206,6 +1213,59 @@ public class SIMRecords extends IccRecords { } 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: super.handleMessage(msg); // IccRecords handles generic record load responses } Loading Loading @@ -1457,11 +1517,25 @@ public class SIMRecords extends IccRecords { * in the result field of an AsyncResult in the response.obj. */ public void getForbiddenPlmns(Message response) { int key = storePendingResponseMessage(response); int key = storePendingTransaction(response); mFh.loadEFTransparent(EF_FPLMN, obtainMessage( 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 public void onReady() { fetchSimRecords(); Loading Loading
src/java/com/android/internal/telephony/uicc/IccFileHandler.java +97 −35 Original line number Diff line number Diff line Loading @@ -94,6 +94,8 @@ public abstract class IccFileHandler extends Handler implements IccConstants { static protected final int EVENT_READ_ICON_DONE = 10; /** Finished retrieving size of record for EFimg now. */ 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 @UnsupportedAppUsage Loading Loading @@ -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 path Path of the EF on the card * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] * int[0] is the record length int[1] is the total length of the EF * file int[3] is the number of records in the EF file So int[0] * * int[3] = int[1] * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the * record length int[1] is the total length of the EF file int[3] is the number of records * in the EF file So int[0] * int[3] = int[1] */ @UnsupportedAppUsage public void getEFLinearRecordSize(int fileid, String path, Message onLoaded) { Loading @@ -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 onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] * int[0] is the record length int[1] is the total length of the EF * file int[3] is the number of records in the EF file So int[0] * * int[3] = int[1] * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] int[0] is the * record length int[1] is the total length of the EF file int[3] is the number of records * in the EF file So int[0] * int[3] = int[1] */ @UnsupportedAppUsage public void getEFLinearRecordSize(int fileid, Message 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 * Loading @@ -263,7 +296,6 @@ public abstract class IccFileHandler extends Handler implements IccConstants { * @param onLoaded * * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]> * */ @UnsupportedAppUsage public void loadEFLinearFixedAll(int fileid, String path, Message onLoaded) { Loading Loading @@ -296,9 +328,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { * @param onLoaded * * ((AsyncResult)(onLoaded.obj)).result is the byte[] * */ @UnsupportedAppUsage public void loadEFTransparent(int fileid, Message onLoaded) { Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE, Loading Loading @@ -473,8 +503,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { recordSize = new int[3]; recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); recordSize[1] = getDataFileSize(data); recordSize[2] = recordSize[1] / recordSize[0]; sendResult(response, recordSize, null); Loading Loading @@ -505,8 +534,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { lc.mRecordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); size = getDataFileSize(data); lc.mCountRecords = size / lc.mRecordSize; Loading Loading @@ -549,8 +577,7 @@ public abstract class IccFileHandler extends Handler implements IccConstants { throw new IccFileTypeMismatch(); } size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); size = getDataFileSize(data); mCi.iccIOForApp(COMMAND_READ_BINARY, fileid, getEFPath(fileid), 0, 0, size, null, null, mAid, Loading Loading @@ -608,6 +635,31 @@ public abstract class IccFileHandler extends Handler implements IccConstants { sendResult(response, result.payload, null); 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) { if (response != null) { sendResult(response, null, exc); Loading Loading @@ -656,4 +708,14 @@ public abstract class IccFileHandler extends Handler implements IccConstants { protected abstract void logd(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)); } }
src/java/com/android/internal/telephony/uicc/IccRecords.java +30 −12 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.telephony.Rlog; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Pair; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.MccTable; Loading Loading @@ -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_SEND_RESPONSE = HANDLER_ACTION_BASE + 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 // Markers for mncLength Loading Loading @@ -344,24 +344,42 @@ public abstract class IccRecords extends Handler implements IccConstants { } /** * Adds a message to the pending requests list by generating a unique * (integer) hash key and returning it. The message should never be null. * Adds a message 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 * @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(); synchronized (mPendingResponses) { mPendingResponses.put(key, msg); Pair<Message, Object> pair = new Pair<Message, Object>(msg, obj); synchronized (mPendingTransactions) { mPendingTransactions.put(key, pair); } 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) { Message m; synchronized (mPendingResponses) { return mPendingResponses.remove(key); public Pair<Message, Object> retrievePendingTransaction(Integer key) { synchronized (mPendingTransactions) { return mPendingTransactions.remove(key); } } Loading
src/java/com/android/internal/telephony/uicc/SIMRecords.java +77 −3 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.telephony.Rlog; import android.telephony.SmsMessage; import android.telephony.SubscriptionInfo; import android.text.TextUtils; import android.util.Pair; import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.MccTable; Loading Loading @@ -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_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 private static final int SIM_RECORD_EVENT_BASE = 0x00; private static final int EVENT_GET_IMSI_DONE = 3 + SIM_RECORD_EVENT_BASE; Loading Loading @@ -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_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_SIZE_DONE = 42 + SIM_RECORD_EVENT_BASE; private static final int EVENT_SET_FPLMN_DONE = 43 + SIM_RECORD_EVENT_BASE; // ***** Constructor public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) { Loading Loading @@ -1194,7 +1200,8 @@ public class SIMRecords extends IccRecords { if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) { if (VDBG) logv("getForbiddenPlmns(): send async response"); isRecordLoadResponse = false; Message response = retrievePendingResponseMessage(msg.arg2); int key = msg.arg2; Message response = retrievePendingTransaction(key).first; if (response != null) { AsyncResult.forMessage( response, Arrays.copyOf(mFplmns, mFplmns.length), null); Loading @@ -1206,6 +1213,59 @@ public class SIMRecords extends IccRecords { } 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: super.handleMessage(msg); // IccRecords handles generic record load responses } Loading Loading @@ -1457,11 +1517,25 @@ public class SIMRecords extends IccRecords { * in the result field of an AsyncResult in the response.obj. */ public void getForbiddenPlmns(Message response) { int key = storePendingResponseMessage(response); int key = storePendingTransaction(response); mFh.loadEFTransparent(EF_FPLMN, obtainMessage( 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 public void onReady() { fetchSimRecords(); Loading