use of android.os.AsyncResult in project android_frameworks_opt_telephony by LineageOS.
the class IconLoader method handleMessage.
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
try {
switch(msg.what) {
case EVENT_READ_EF_IMG_RECOED_DONE:
ar = (AsyncResult) msg.obj;
if (handleImageDescriptor((byte[]) ar.result)) {
readIconData();
} else {
throw new Exception("Unable to parse image descriptor");
}
break;
case EVENT_READ_ICON_DONE:
CatLog.d(this, "load icon done");
ar = (AsyncResult) msg.obj;
byte[] rawData = ((byte[]) ar.result);
if (mId.mCodingScheme == ImageDescriptor.CODING_SCHEME_BASIC) {
mCurrentIcon = parseToBnW(rawData, rawData.length);
mIconsCache.put(mRecordNumber, mCurrentIcon);
postIcon();
} else if (mId.mCodingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) {
mIconData = rawData;
readClut();
} else {
CatLog.d(this, "else /postIcon ");
postIcon();
}
break;
case EVENT_READ_CLUT_DONE:
ar = (AsyncResult) msg.obj;
byte[] clut = ((byte[]) ar.result);
mCurrentIcon = parseToRGB(mIconData, mIconData.length, false, clut);
mIconsCache.put(mRecordNumber, mCurrentIcon);
postIcon();
break;
}
} catch (Exception e) {
CatLog.d(this, "Icon load failed");
// post null icon back to the caller.
postIcon();
}
}
use of android.os.AsyncResult in project android_frameworks_opt_telephony by LineageOS.
the class RuimRecords method onAllRecordsLoaded.
@Override
protected void onAllRecordsLoaded() {
if (DBG)
log("record load complete");
// FIXME: CSIM IMSI may not contain the MNC.
if (false) {
String operator = getRUIMOperatorNumeric();
if (!TextUtils.isEmpty(operator)) {
log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" + operator + "'");
log("update icc_operator_numeric=" + operator);
mTelephonyManager.setSimOperatorNumericForPhone(mParentApp.getPhoneId(), operator);
} else {
log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
}
String imsi = getIMSI();
if (!TextUtils.isEmpty(imsi)) {
log("onAllRecordsLoaded set mcc imsi=" + (VDBG ? ("=" + imsi) : ""));
mTelephonyManager.setSimCountryIsoForPhone(mParentApp.getPhoneId(), MccTable.countryCodeForMcc(imsi.substring(0, 3)));
} else {
log("onAllRecordsLoaded empty imsi skipping setting mcc");
}
}
Resources resource = Resources.getSystem();
if (resource.getBoolean(com.android.internal.R.bool.config_use_sim_language_file)) {
setSimLanguage(mEFli, mEFpl);
}
mLoaded.set(true);
mRecordsLoadedRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
// TODO: The below is hacky since the SubscriptionController may not be ready at this time.
if (!TextUtils.isEmpty(mMdn)) {
int phoneId = mParentApp.getUiccProfile().getPhoneId();
int subId = SubscriptionController.getInstance().getSubIdUsingPhoneId(phoneId);
if (SubscriptionManager.isValidSubscriptionId(subId)) {
SubscriptionManager.from(mContext).setDisplayNumber(mMdn, subId);
} else {
log("Cannot call setDisplayNumber: invalid subId");
}
}
}
use of android.os.AsyncResult in project android_frameworks_opt_telephony by LineageOS.
the class SIMRecords method onLockedAllRecordsLoaded.
private void onLockedAllRecordsLoaded() {
setSimLanguageFromEF();
setVoiceCallForwardingFlagFromSimRecords();
if (mLockedRecordsReqReason == LOCKED_RECORDS_REQ_REASON_LOCKED) {
mLockedRecordsLoadedRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
} else if (mLockedRecordsReqReason == LOCKED_RECORDS_REQ_REASON_NETWORK_LOCKED) {
mNetworkLockedRecordsLoadedRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
} else {
loge("onLockedAllRecordsLoaded: unexpected mLockedRecordsReqReason " + mLockedRecordsReqReason);
}
}
use of android.os.AsyncResult in project android_frameworks_opt_telephony by LineageOS.
the class SIMRecords method handleMessage.
// ***** Overridden from Handler
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
AdnRecord adn;
byte[] data;
boolean isRecordLoadResponse = false;
if (mDestroyed.get()) {
loge("Received message " + msg + "[" + msg.what + "] " + " while being destroyed. Ignoring.");
return;
}
try {
switch(msg.what) {
/* IO events */
case EVENT_GET_IMSI_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
loge("Exception querying IMSI, Exception:" + ar.exception);
break;
}
setImsi((String) ar.result);
break;
case EVENT_GET_MBI_DONE:
boolean isValidMbdn;
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
isValidMbdn = false;
if (ar.exception == null) {
// Refer TS 51.011 Section 10.3.44 for content details
log("EF_MBI: " + IccUtils.bytesToHexString(data));
// Voice mail record number stored first
mMailboxIndex = data[0] & 0xff;
// check if dailing numbe id valid
if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {
log("Got valid mailbox number for MBDN");
isValidMbdn = true;
}
}
// one more record to load
mRecordsToLoad += 1;
if (isValidMbdn) {
// Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED
new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6, mMailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
} else {
// If this EF not present, try mailbox as in CPHS standard
// CPHS (CPHS4_2.WW6) is a european standard.
new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1, 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
}
break;
case EVENT_GET_CPHS_MAILBOX_DONE:
case EVENT_GET_MBDN_DONE:
// Resetting the voice mail number and voice mail tag to null
// as these should be updated from the data read from EF_MBDN.
// If they are not reset, incase of invalid data/exception these
// variables are retaining their previous values and are
// causing invalid voice mailbox info display to user.
mVoiceMailNum = null;
mVoiceMailTag = null;
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
log("Invalid or missing EF" + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]"));
if (msg.what == EVENT_GET_MBDN_DONE) {
// load CPHS on fail...
// FIXME right now, only load line1's CPHS voice mail entry
mRecordsToLoad += 1;
new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1, 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
}
break;
}
adn = (AdnRecord) ar.result;
log("VM: " + adn + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]"));
if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) {
// Bug #645770 fall back to CPHS
// FIXME should use SST to decide
// FIXME right now, only load line1's CPHS voice mail entry
mRecordsToLoad += 1;
new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1, 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
break;
}
mVoiceMailNum = adn.getNumber();
mVoiceMailTag = adn.getAlphaTag();
break;
case EVENT_GET_MSISDN_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
log("Invalid or missing EF[MSISDN]");
break;
}
adn = (AdnRecord) ar.result;
mMsisdn = adn.getNumber();
mMsisdnTag = adn.getAlphaTag();
log("MSISDN: " + /*mMsisdn*/
Rlog.pii(LOG_TAG, mMsisdn));
break;
case EVENT_SET_MSISDN_DONE:
isRecordLoadResponse = false;
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
mMsisdn = mNewMsisdn;
mMsisdnTag = mNewMsisdnTag;
log("Success to update EF[MSISDN]");
}
if (ar.userObj != null) {
AsyncResult.forMessage(((Message) ar.userObj)).exception = ar.exception;
((Message) ar.userObj).sendToTarget();
}
break;
case EVENT_GET_MWIS_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (DBG)
log("EF_MWIS : " + IccUtils.bytesToHexString(data));
if (ar.exception != null) {
if (DBG)
log("EVENT_GET_MWIS_DONE exception = " + ar.exception);
break;
}
if ((data[0] & 0xff) == 0xff) {
if (DBG)
log("SIMRecords: Uninitialized record MWIS");
break;
}
mEfMWIS = data;
break;
case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (DBG)
log("EF_CPHS_MWI: " + IccUtils.bytesToHexString(data));
if (ar.exception != null) {
if (DBG) {
log("EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE exception = " + ar.exception);
}
break;
}
mEfCPHS_MWI = data;
break;
case EVENT_GET_ICCID_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
break;
}
mIccId = IccUtils.bcdToString(data, 0, data.length);
mFullIccId = IccUtils.bchToString(data, 0, data.length);
log("iccid: " + SubscriptionInfo.givePrintableIccid(mFullIccId));
break;
case EVENT_GET_AD_DONE:
isRecordLoadResponse = true;
mMncLength = UNKNOWN;
try {
if (!mCarrierTestOverride.isInTestMode()) {
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
break;
}
log("EF_AD: " + IccUtils.bytesToHexString(data));
if (data.length < 3) {
log("Corrupt AD data on SIM");
break;
}
if (data.length == 3) {
log("MNC length not present in EF_AD");
break;
}
int len = data[3] & 0xf;
if (len == 2 || len == 3) {
mMncLength = len;
} else {
log("Received invalid or unset MNC Length=" + len);
}
}
} finally {
updateOperatorPlmn();
}
break;
case EVENT_GET_SPN_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
getSpnFsm(false, ar);
break;
case EVENT_GET_CFF_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
mEfCff = null;
} else {
log("EF_CFF_CPHS: " + IccUtils.bytesToHexString(data));
mEfCff = data;
}
break;
case EVENT_GET_SPDI_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
break;
}
parseEfSpdi(data);
break;
case EVENT_UPDATE_DONE:
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
logw("update failed. ", ar.exception);
}
break;
case EVENT_GET_PNN_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
break;
}
SimTlv tlv = new SimTlv(data, 0, data.length);
for (; tlv.isValidObject(); tlv.nextObject()) {
if (tlv.getTag() == TAG_FULL_NETWORK_NAME) {
mPnnHomeName = IccUtils.networkNameToString(tlv.getData(), 0, tlv.getData().length);
log("PNN: " + mPnnHomeName);
break;
}
}
break;
case EVENT_GET_ALL_SMS_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
break;
}
handleSmses((ArrayList<byte[]>) ar.result);
break;
case EVENT_MARK_SMS_READ_DONE:
log("marked read: sms " + msg.arg1);
break;
case EVENT_SMS_ON_SIM:
isRecordLoadResponse = false;
ar = (AsyncResult) msg.obj;
Integer index = (Integer) ar.result;
if (ar.exception != null || index == null) {
loge("Error on SMS_ON_SIM with exp " + ar.exception + " index " + index);
} else {
log("READ EF_SMS RECORD index=" + index);
mFh.loadEFLinearFixed(EF_SMS, index, obtainMessage(EVENT_GET_SMS_DONE));
}
break;
case EVENT_GET_SMS_DONE:
isRecordLoadResponse = false;
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
handleSms((byte[]) ar.result);
} else {
loge("Error on GET_SMS with exp " + ar.exception);
}
break;
case EVENT_GET_SST_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
break;
}
mUsimServiceTable = new UsimServiceTable(data);
if (DBG)
log("SST: " + mUsimServiceTable);
break;
case EVENT_GET_INFO_CPHS_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
break;
}
mCphsInfo = (byte[]) ar.result;
if (DBG)
log("iCPHS: " + IccUtils.bytesToHexString(mCphsInfo));
break;
case EVENT_SET_MBDN_DONE:
isRecordLoadResponse = false;
ar = (AsyncResult) msg.obj;
if (DBG)
log("EVENT_SET_MBDN_DONE ex:" + ar.exception);
if (ar.exception == null) {
mVoiceMailNum = mNewVoiceMailNum;
mVoiceMailTag = mNewVoiceMailTag;
}
if (isCphsMailboxEnabled()) {
adn = new AdnRecord(mVoiceMailTag, mVoiceMailNum);
Message onCphsCompleted = (Message) ar.userObj;
/* write to cphs mailbox whenever it is available but
* we only need notify caller once if both updating are
* successful.
*
* so if set_mbdn successful, notify caller here and set
* onCphsCompleted to null
*/
if (ar.exception == null && ar.userObj != null) {
AsyncResult.forMessage(((Message) ar.userObj)).exception = null;
((Message) ar.userObj).sendToTarget();
if (DBG)
log("Callback with MBDN successful.");
onCphsCompleted = null;
}
new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null, obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onCphsCompleted));
} else {
if (ar.userObj != null) {
CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (ar.exception != null && configManager != null) {
PersistableBundle b = configManager.getConfigForSubId(SubscriptionController.getInstance().getSubIdUsingPhoneId(mParentApp.getPhoneId()));
if (b != null && b.getBoolean(CarrierConfigManager.KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL)) {
// GsmCdmaPhone will store vm number on device
// when IccVmNotSupportedException occurred
AsyncResult.forMessage(((Message) ar.userObj)).exception = new IccVmNotSupportedException("Update SIM voice mailbox error");
} else {
AsyncResult.forMessage(((Message) ar.userObj)).exception = ar.exception;
}
} else {
AsyncResult.forMessage(((Message) ar.userObj)).exception = ar.exception;
}
((Message) ar.userObj).sendToTarget();
}
}
break;
case EVENT_SET_CPHS_MAILBOX_DONE:
isRecordLoadResponse = false;
ar = (AsyncResult) msg.obj;
if (ar.exception == null) {
mVoiceMailNum = mNewVoiceMailNum;
mVoiceMailTag = mNewVoiceMailTag;
} else {
if (DBG)
log("Set CPHS MailBox with exception: " + ar.exception);
}
if (ar.userObj != null) {
if (DBG)
log("Callback with CPHS MB successful.");
AsyncResult.forMessage(((Message) ar.userObj)).exception = ar.exception;
((Message) ar.userObj).sendToTarget();
}
break;
case EVENT_GET_CFIS_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
mEfCfis = null;
} else {
log("EF_CFIS: " + IccUtils.bytesToHexString(data));
mEfCfis = data;
}
break;
case EVENT_GET_CSP_CPHS_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
loge("Exception in fetching EF_CSP data " + ar.exception);
break;
}
data = (byte[]) ar.result;
log("EF_CSP: " + IccUtils.bytesToHexString(data));
handleEfCspData(data);
break;
case EVENT_GET_GID1_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
loge("Exception in get GID1 " + ar.exception);
mGid1 = null;
break;
}
mGid1 = IccUtils.bytesToHexString(data);
log("GID1: " + mGid1);
break;
case EVENT_GET_GID2_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null) {
loge("Exception in get GID2 " + ar.exception);
mGid2 = null;
break;
}
mGid2 = IccUtils.bytesToHexString(data);
log("GID2: " + mGid2);
break;
case EVENT_GET_PLMN_W_ACT_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null || data == null) {
loge("Failed getting User PLMN with Access Tech Records: " + ar.exception);
break;
} else {
log("Received a PlmnActRecord, raw=" + IccUtils.bytesToHexString(data));
mPlmnActRecords = PlmnActRecord.getRecords(data);
if (VDBG)
log("PlmnActRecords=" + Arrays.toString(mPlmnActRecords));
}
break;
case EVENT_GET_OPLMN_W_ACT_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null || data == null) {
loge("Failed getting Operator PLMN with Access Tech Records: " + ar.exception);
break;
} else {
log("Received a PlmnActRecord, raw=" + IccUtils.bytesToHexString(data));
mOplmnActRecords = PlmnActRecord.getRecords(data);
if (VDBG)
log("OplmnActRecord[]=" + Arrays.toString(mOplmnActRecords));
}
break;
case EVENT_GET_HPLMN_W_ACT_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null || data == null) {
loge("Failed getting Home PLMN with Access Tech Records: " + ar.exception);
break;
} else {
log("Received a PlmnActRecord, raw=" + IccUtils.bytesToHexString(data));
mHplmnActRecords = PlmnActRecord.getRecords(data);
log("HplmnActRecord[]=" + Arrays.toString(mHplmnActRecords));
}
break;
case EVENT_GET_EHPLMN_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null || data == null) {
loge("Failed getting Equivalent Home PLMNs: " + ar.exception);
break;
} else {
mEhplmns = parseBcdPlmnList(data, "Equivalent Home");
}
break;
case EVENT_GET_FPLMN_DONE:
isRecordLoadResponse = true;
ar = (AsyncResult) msg.obj;
data = (byte[]) ar.result;
if (ar.exception != null || data == null) {
loge("Failed getting Forbidden PLMNs: " + ar.exception);
} else {
mFplmns = parseBcdPlmnList(data, "Forbidden");
}
if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) {
if (VDBG)
logv("getForbiddenPlmns(): send async response");
isRecordLoadResponse = false;
int key = msg.arg2;
Message response = retrievePendingTransaction(key).first;
if (response != null) {
if (ar.exception == null && data != null && mFplmns != null) {
AsyncResult.forMessage(response, Arrays.copyOf(mFplmns, mFplmns.length), null);
} else {
AsyncResult.forMessage(response, null, ar.exception);
}
response.sendToTarget();
} else {
loge("Failed to retrieve a response message for FPLMN");
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:
// IccRecords handles generic record load responses
super.handleMessage(msg);
}
} catch (RuntimeException exc) {
// I don't want these exceptions to be fatal
logw("Exception parsing SIM record", exc);
} finally {
// Count up record load responses even if they are fails
if (isRecordLoadResponse) {
onRecordLoaded();
}
}
}
use of android.os.AsyncResult in project android_frameworks_opt_telephony by LineageOS.
the class UiccCarrierPrivilegeRules method handleMessage.
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
// 0 means ARA-D and 1 means ARA-M.
mAIDInUse = msg.arg2;
switch(msg.what) {
case EVENT_OPEN_LOGICAL_CHANNEL_DONE:
log("EVENT_OPEN_LOGICAL_CHANNEL_DONE");
ar = (AsyncResult) msg.obj;
if (ar.exception == null && ar.result != null) {
mChannelId = ((int[]) ar.result)[0];
mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2, P3, DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId, mAIDInUse));
} else {
if (shouldRetry(ar, mRetryCount)) {
log("should retry");
mRetryCount++;
removeCallbacks(mRetryRunnable);
postDelayed(mRetryRunnable, RETRY_INTERVAL_MS);
} else {
if (mAIDInUse == ARAD) {
// Open logical channel with ARA_M.
mRules = "";
openChannel(ARAM);
}
if (mAIDInUse == ARAM) {
if (mCheckedRules) {
updateState(STATE_LOADED, "Success!");
} else {
// if rules cannot be read from both ARA_D and ARA_M applet,
// fallback to PKCS15-based ARF.
log("No ARA, try ARF next.");
if (ar.exception instanceof CommandException && ((CommandException) (ar.exception)).getCommandError() != CommandException.Error.NO_SUCH_ELEMENT) {
updateStatusMessage("No ARA due to " + ((CommandException) (ar.exception)).getCommandError());
}
mUiccPkcs15 = new UiccPkcs15(mUiccProfile, obtainMessage(EVENT_PKCS15_READ_DONE));
}
}
}
}
break;
case EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE:
log("EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE");
ar = (AsyncResult) msg.obj;
if (ar.exception == null && ar.result != null) {
IccIoResult response = (IccIoResult) ar.result;
if (response.sw1 == 0x90 && response.sw2 == 0x00 && response.payload != null && response.payload.length > 0) {
try {
mRules += IccUtils.bytesToHexString(response.payload).toUpperCase(Locale.US);
if (isDataComplete()) {
// TODO: here's where AccessRules are being updated from the psim
// b/139133814
mAccessRules.addAll(parseRules(mRules));
if (mAIDInUse == ARAD) {
mCheckedRules = true;
} else {
updateState(STATE_LOADED, "Success!");
}
} else {
mUiccProfile.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2_EXTENDED_DATA, P3, DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId, mAIDInUse));
break;
}
} catch (IllegalArgumentException | IndexOutOfBoundsException ex) {
if (mAIDInUse == ARAM) {
updateState(STATE_ERROR, "Error parsing rules: " + ex);
}
}
} else {
if (mAIDInUse == ARAM) {
String errorMsg = "Invalid response: payload=" + response.payload + " sw1=" + response.sw1 + " sw2=" + response.sw2;
updateState(STATE_ERROR, errorMsg);
}
}
} else {
String errorMsg = "Error reading value from SIM via " + ((mAIDInUse == ARAD) ? "ARAD" : "ARAM") + " due to ";
if (ar.exception instanceof CommandException) {
CommandException.Error errorCode = ((CommandException) (ar.exception)).getCommandError();
errorMsg += "error code : " + errorCode;
} else {
errorMsg += "unknown exception : " + ar.exception.getMessage();
}
if (mAIDInUse == ARAD) {
updateStatusMessage(errorMsg);
} else {
updateState(STATE_ERROR, errorMsg);
}
}
mUiccProfile.iccCloseLogicalChannel(mChannelId, obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE, 0, mAIDInUse));
mChannelId = -1;
break;
case EVENT_CLOSE_LOGICAL_CHANNEL_DONE:
log("EVENT_CLOSE_LOGICAL_CHANNEL_DONE");
if (mAIDInUse == ARAD) {
// Close logical channel with ARA_D and then open logical channel with ARA_M.
mRules = "";
openChannel(ARAM);
}
break;
case EVENT_PKCS15_READ_DONE:
log("EVENT_PKCS15_READ_DONE");
if (mUiccPkcs15 == null || mUiccPkcs15.getRules() == null) {
updateState(STATE_ERROR, "No ARA or ARF.");
} else {
for (String cert : mUiccPkcs15.getRules()) {
UiccAccessRule accessRule = new UiccAccessRule(IccUtils.hexStringToBytes(cert), "", 0x00);
mAccessRules.add(accessRule);
}
updateState(STATE_LOADED, "Success!");
}
break;
default:
Rlog.e(LOG_TAG, "Unknown event " + msg.what);
}
}
Aggregations