/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.uicc;

import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.os.AsyncResult;
import android.os.Message;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
import android.telephony.SmsMessage;
import android.telephony.SubscriptionInfo;
import android.text.TextUtils;

import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.SmsConstants;
import com.android.internal.telephony.SubscriptionController;
import com.android.internal.telephony.gsm.SimTlv;
import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * {@hide}
 */
public class SIMRecords extends IccRecords {
    protected static final String LOG_TAG = "SIMRecords";

    private static final boolean CRASH_RIL = false;

    private static final boolean VDBG = false;

    // ***** Instance Variables

    @UnsupportedAppUsage
    VoiceMailConstants mVmConfig;

    // ***** Cached SIM State; cleared on channel close

    private int mCallForwardingStatus;

    /**
     * States only used by getSpnFsm FSM
     */
    private GetSpnFsmState mSpnState;

    /** CPHS service information (See CPHS 4.2 B.3.1.1)
     *  It will be set in onSimReady if reading GET_CPHS_INFO successfully
     *  mCphsInfo[0] is CPHS Phase
     *  mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table
     */
    private byte[] mCphsInfo = null;
    boolean mCspPlmnEnabled = true;

    @UnsupportedAppUsage
    byte[] mEfMWIS = null;
    @UnsupportedAppUsage
    byte[] mEfCPHS_MWI =null;
    @UnsupportedAppUsage
    byte[] mEfCff = null;
    @UnsupportedAppUsage
    byte[] mEfCfis = null;

    @UnsupportedAppUsage
    byte[] mEfLi = null;
    @UnsupportedAppUsage
    byte[] mEfPl = null;

    @UnsupportedAppUsage
    UsimServiceTable mUsimServiceTable;

    @Override
    public String toString() {
        return "SimRecords: " + super.toString()
                + " mVmConfig" + mVmConfig
                + " callForwardingEnabled=" + mCallForwardingStatus
                + " spnState=" + mSpnState
                + " mCphsInfo=" + mCphsInfo
                + " mCspPlmnEnabled=" + mCspPlmnEnabled
                + " efMWIS=" + mEfMWIS
                + " efCPHS_MWI=" + mEfCPHS_MWI
                + " mEfCff=" + mEfCff
                + " mEfCfis=" + mEfCfis
                + " getOperatorNumeric=" + getOperatorNumeric();
    }

    // ***** Constants

    // From TS 51.011 EF[SPDI] section
    static final int TAG_SPDI = 0xA3;
    static final int TAG_SPDI_PLMN_LIST = 0x80;

    // Full Name IEI from TS 24.008
    static final int TAG_FULL_NETWORK_NAME = 0x43;

    // Short Name IEI from TS 24.008
    static final int TAG_SHORT_NETWORK_NAME = 0x45;

    // active CFF from CPHS 4.2 B.4.5
    static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a;
    static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05;
    static final int CFF_LINE1_MASK = 0x0f;
    static final int CFF_LINE1_RESET = 0xf0;

    // CPHS Service Table (See CPHS 4.2 B.3.1)
    private static final int CPHS_SST_MBN_MASK = 0x30;
    private static final int CPHS_SST_MBN_ENABLED = 0x30;

    // EF_CFIS related constants
    // Spec reference TS 51.011 section 10.3.46.
    private static final int CFIS_BCD_NUMBER_LENGTH_OFFSET = 2;
    private static final int CFIS_TON_NPI_OFFSET = 3;
    private static final int CFIS_ADN_CAPABILITY_ID_OFFSET = 14;
    private static final int CFIS_ADN_EXTENSION_ID_OFFSET = 15;

    // ***** Event Constants
    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_ICCID_DONE = 4 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_MBI_DONE = 5 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_MBDN_DONE = 6 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_MWIS_DONE = 7 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_AD_DONE = 9 + SIM_RECORD_EVENT_BASE; // Admin data on SIM
    private static final int EVENT_GET_MSISDN_DONE = 10 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_SPN_DONE = 12 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_SPDI_DONE = 13 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_UPDATE_DONE = 14 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_PNN_DONE = 15 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_SST_DONE = 17 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_ALL_SMS_DONE = 18 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_MARK_SMS_READ_DONE = 19 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_SET_MBDN_DONE = 20 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_SMS_ON_SIM = 21 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_SMS_DONE = 22 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_CFF_DONE = 24 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_INFO_CPHS_DONE = 26 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_SET_MSISDN_DONE = 30 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_CFIS_DONE = 32 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_CSP_CPHS_DONE = 33 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_GID1_DONE = 34 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_GID2_DONE = 36 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_PLMN_W_ACT_DONE = 37 + SIM_RECORD_EVENT_BASE;
    private static final int EVENT_GET_OPLMN_W_ACT_DONE = 38 + 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_FPLMN_DONE = 41 + SIM_RECORD_EVENT_BASE;

    // TODO: Possibly move these to IccRecords.java
    private static final int SYSTEM_EVENT_BASE = 0x100;
    private static final int EVENT_APP_LOCKED = 2 + SYSTEM_EVENT_BASE;
    private static final int EVENT_APP_NETWORK_LOCKED = 3 + SYSTEM_EVENT_BASE;


    // ***** Constructor

    public SIMRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
        super(app, c, ci);

        mAdnCache = new AdnRecordCache(mFh);

        mVmConfig = new VoiceMailConstants();

        mRecordsRequested = false;  // No load request is made till SIM ready
        mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE;

        // recordsToLoad is set to 0 because no requests are made yet
        mRecordsToLoad = 0;

        mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);

        // Start off by setting empty state
        resetRecords();
        mParentApp.registerForReady(this, EVENT_APP_READY, null);
        mParentApp.registerForLocked(this, EVENT_APP_LOCKED, null);
        mParentApp.registerForNetworkLocked(this, EVENT_APP_NETWORK_LOCKED, null);
        if (DBG) log("SIMRecords X ctor this=" + this);
    }

    @Override
    public void dispose() {
        if (DBG) log("Disposing SIMRecords this=" + this);
        //Unregister for all events
        mCi.unSetOnSmsOnSim(this);
        mParentApp.unregisterForReady(this);
        mParentApp.unregisterForLocked(this);
        mParentApp.unregisterForNetworkLocked(this);
        resetRecords();
        super.dispose();
    }

    @Override
    protected void finalize() {
        if (DBG) log("finalized");
    }

    protected void resetRecords() {
        mImsi = null;
        mMsisdn = null;
        mVoiceMailNum = null;
        mMncLength = UNINITIALIZED;
        log("setting0 mMncLength" + mMncLength);
        mIccId = null;
        mFullIccId = null;
        mCarrierNameDisplayCondition = DEFAULT_CARRIER_NAME_DISPLAY_CONDITION;
        mEfMWIS = null;
        mEfCPHS_MWI = null;
        mSpdi = null;
        mPnnHomeName = null;
        mGid1 = null;
        mGid2 = null;
        mPlmnActRecords = null;
        mOplmnActRecords = null;
        mHplmnActRecords = null;
        mFplmns = null;
        mEhplmns = null;

        mAdnCache.reset();

        log("SIMRecords: onRadioOffOrNotAvailable set 'gsm.sim.operator.numeric' to operator=null");
        log("update icc_operator_numeric=" + null);
        mTelephonyManager.setSimOperatorNumericForPhone(mParentApp.getPhoneId(), "");
        mTelephonyManager.setSimOperatorNameForPhone(mParentApp.getPhoneId(), "");
        mTelephonyManager.setSimCountryIsoForPhone(mParentApp.getPhoneId(), "");

        // recordsRequested is set to false indicating that the SIM
        // read requests made so far are not valid. This is set to
        // true only when fresh set of read requests are made.
        mRecordsRequested = false;
        mLockedRecordsReqReason = LOCKED_RECORDS_REQ_REASON_NONE;
        mLoaded.set(false);
    }

    //***** Public Methods

    @UnsupportedAppUsage
    @Override
    public String getMsisdnNumber() {
        return mMsisdn;
    }

    @Override
    public UsimServiceTable getUsimServiceTable() {
        return mUsimServiceTable;
    }

    @UnsupportedAppUsage
    private int getExtFromEf(int ef) {
        int ext;
        switch (ef) {
            case EF_MSISDN:
                /* For USIM apps use EXT5. (TS 31.102 Section 4.2.37) */
                if (mParentApp.getType() == AppType.APPTYPE_USIM) {
                    ext = EF_EXT5;
                } else {
                    ext = EF_EXT1;
                }
                break;
            default:
                ext = EF_EXT1;
        }
        return ext;
    }

    /**
     * Set subscriber number to SIM record
     *
     * The subscriber number is stored in EF_MSISDN (TS 51.011)
     *
     * When the operation is complete, onComplete will be sent to its handler
     *
     * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters)
     * @param number dialing number (up to 20 digits)
     *        if the number starts with '+', then set to international TOA
     * @param onComplete
     *        onComplete.obj will be an AsyncResult
     *        ((AsyncResult)onComplete.obj).exception == null on success
     *        ((AsyncResult)onComplete.obj).exception != null on fail
     */
    @Override
    public void setMsisdnNumber(String alphaTag, String number,
            Message onComplete) {

        // If the SIM card is locked by PIN, we will set EF_MSISDN fail.
        // In that case, msisdn and msisdnTag should not be update.
        mNewMsisdn = number;
        mNewMsisdnTag = alphaTag;

        if(DBG) log("Set MSISDN: " + mNewMsisdnTag + " " + /*mNewMsisdn*/
                Rlog.pii(LOG_TAG, mNewMsisdn));

        AdnRecord adn = new AdnRecord(mNewMsisdnTag, mNewMsisdn);

        new AdnRecordLoader(mFh).updateEF(adn, EF_MSISDN, getExtFromEf(EF_MSISDN), 1, null,
                obtainMessage(EVENT_SET_MSISDN_DONE, onComplete));
    }

    @Override
    public String getMsisdnAlphaTag() {
        return mMsisdnTag;
    }

    @UnsupportedAppUsage
    @Override
    public String getVoiceMailNumber() {
        return mVoiceMailNum;
    }

    /**
     * Set voice mail number to SIM record
     *
     * The voice mail number can be stored either in EF_MBDN (TS 51.011) or
     * EF_MAILBOX_CPHS (CPHS 4.2)
     *
     * If EF_MBDN is available, store the voice mail number to EF_MBDN
     *
     * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS
     *
     * So the voice mail number will be stored in both EFs if both are available
     *
     * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail.
     *
     * When the operation is complete, onComplete will be sent to its handler
     *
     * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters)
     * @param voiceNumber dailing nubmer (upto 20 digits)
     *        if the number is start with '+', then set to international TOA
     * @param onComplete
     *        onComplete.obj will be an AsyncResult
     *        ((AsyncResult)onComplete.obj).exception == null on success
     *        ((AsyncResult)onComplete.obj).exception != null on fail
     */
    @Override
    public void setVoiceMailNumber(String alphaTag, String voiceNumber,
            Message onComplete) {
        if (mIsVoiceMailFixed) {
            AsyncResult.forMessage((onComplete)).exception =
                    new IccVmFixedException("Voicemail number is fixed by operator");
            onComplete.sendToTarget();
            return;
        }

        mNewVoiceMailNum = voiceNumber;
        mNewVoiceMailTag = alphaTag;

        AdnRecord adn = new AdnRecord(mNewVoiceMailTag, mNewVoiceMailNum);

        if (mMailboxIndex != 0 && mMailboxIndex != 0xff) {

            new AdnRecordLoader(mFh).updateEF(adn, EF_MBDN, EF_EXT6,
                    mMailboxIndex, null,
                    obtainMessage(EVENT_SET_MBDN_DONE, onComplete));

        } else if (isCphsMailboxEnabled()) {

            new AdnRecordLoader(mFh).updateEF(adn, EF_MAILBOX_CPHS,
                    EF_EXT1, 1, null,
                    obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete));

        } else {
            AsyncResult.forMessage((onComplete)).exception =
                    new IccVmNotSupportedException("Update SIM voice mailbox error");
            onComplete.sendToTarget();
        }
    }

    @Override
    public String getVoiceMailAlphaTag()
    {
        return mVoiceMailTag;
    }

    /**
     * Sets the SIM voice message waiting indicator records
     * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
     * @param countWaiting The number of messages waiting, if known. Use
     *                     -1 to indicate that an unknown number of
     *                      messages are waiting
     */
    @Override
    public void
    setVoiceMessageWaiting(int line, int countWaiting) {
        if (line != 1) {
            // only profile 1 is supported
            return;
        }

        try {
            if (mEfMWIS != null) {
                // TS 51.011 10.3.45

                // lsb of byte 0 is 'voicemail' status
                mEfMWIS[0] = (byte)((mEfMWIS[0] & 0xfe)
                                    | (countWaiting == 0 ? 0 : 1));

                // byte 1 is the number of voice messages waiting
                if (countWaiting < 0) {
                    // The spec does not define what this should be
                    // if we don't know the count
                    mEfMWIS[1] = 0;
                } else {
                    mEfMWIS[1] = (byte) countWaiting;
                }

                mFh.updateEFLinearFixed(
                    EF_MWIS, 1, mEfMWIS, null,
                    obtainMessage (EVENT_UPDATE_DONE, EF_MWIS, 0));
            }

            if (mEfCPHS_MWI != null) {
                    // Refer CPHS4_2.WW6 B4.2.3
                mEfCPHS_MWI[0] = (byte)((mEfCPHS_MWI[0] & 0xf0)
                            | (countWaiting == 0 ? 0x5 : 0xa));
                mFh.updateEFTransparent(
                    EF_VOICE_MAIL_INDICATOR_CPHS, mEfCPHS_MWI,
                    obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS));
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            logw("Error saving voice mail state to SIM. Probably malformed SIM record", ex);
        }
    }

    // Validate data is not null and not empty.
    private boolean validEfCfis(byte[] data) {
        if (data != null) {
            if (data[0] < 1 || data[0] > 4) {
                // The MSP (Multiple Subscriber Profile) byte should be between
                // 1 and 4 according to ETSI TS 131 102 v11.3.0 section 4.2.64.
                logw("MSP byte: " + data[0] + " is not between 1 and 4", null);
            }
            // empty EF_CFIS should be considered as call forward disabled
            for (byte b : data) {
                if (b != (byte) 0xFF) {
                    return true;
                }
            }
        }
        return false;
    }

    public int getVoiceMessageCount() {
        boolean voiceMailWaiting = false;
        int countVoiceMessages = DEFAULT_VOICE_MESSAGE_COUNT;
        if (mEfMWIS != null) {
            // Use this data if the EF[MWIS] exists and
            // has been loaded
            // Refer TS 51.011 Section 10.3.45 for the content description
            voiceMailWaiting = ((mEfMWIS[0] & 0x01) != 0);
            countVoiceMessages = mEfMWIS[1] & 0xff;

            if (voiceMailWaiting && (countVoiceMessages == 0 || countVoiceMessages == 0xff)) {
                // Unknown count = -1
                countVoiceMessages = UNKNOWN_VOICE_MESSAGE_COUNT;
            }
            if (DBG) log(" VoiceMessageCount from SIM MWIS = " + countVoiceMessages);
        } else if (mEfCPHS_MWI != null) {
            // use voice mail count from CPHS
            int indicator = (int) (mEfCPHS_MWI[0] & 0xf);

            // Refer CPHS4_2.WW6 B4.2.3
            if (indicator == 0xA) {
                // Unknown count = -1
                countVoiceMessages = UNKNOWN_VOICE_MESSAGE_COUNT;
            } else if (indicator == 0x5) {
                countVoiceMessages = 0;
            }
            if (DBG) log(" VoiceMessageCount from SIM CPHS = " + countVoiceMessages);
        }
        return countVoiceMessages;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getVoiceCallForwardingFlag() {
        return mCallForwardingStatus;
    }

    /**
     * {@inheritDoc}
     */
    @UnsupportedAppUsage
    @Override
    public void setVoiceCallForwardingFlag(int line, boolean enable, String dialNumber) {

        if (line != 1) return; // only line 1 is supported

        mCallForwardingStatus = enable ? CALL_FORWARDING_STATUS_ENABLED :
                CALL_FORWARDING_STATUS_DISABLED;

        mRecordsEventsRegistrants.notifyResult(EVENT_CFI);

        try {
            if (validEfCfis(mEfCfis)) {
                // lsb is of byte f1 is voice status
                if (enable) {
                    mEfCfis[1] |= 1;
                } else {
                    mEfCfis[1] &= 0xfe;
                }

                log("setVoiceCallForwardingFlag: enable=" + enable
                        + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));

                // Update dialNumber if not empty and CFU is enabled.
                // Spec reference for EF_CFIS contents, TS 51.011 section 10.3.46.
                if (enable && !TextUtils.isEmpty(dialNumber)) {
                    logv("EF_CFIS: updating cf number, " + Rlog.pii(LOG_TAG, dialNumber));
                    byte[] bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(
                            dialNumber, PhoneNumberUtils.BCD_EXTENDED_TYPE_EF_ADN);

                    System.arraycopy(bcdNumber, 0, mEfCfis, CFIS_TON_NPI_OFFSET, bcdNumber.length);

                    mEfCfis[CFIS_BCD_NUMBER_LENGTH_OFFSET] = (byte) (bcdNumber.length);
                    mEfCfis[CFIS_ADN_CAPABILITY_ID_OFFSET] = (byte) 0xFF;
                    mEfCfis[CFIS_ADN_EXTENSION_ID_OFFSET] = (byte) 0xFF;
                }

                mFh.updateEFLinearFixed(
                        EF_CFIS, 1, mEfCfis, null,
                        obtainMessage (EVENT_UPDATE_DONE, EF_CFIS));
            } else {
                log("setVoiceCallForwardingFlag: ignoring enable=" + enable
                        + " invalid mEfCfis=" + IccUtils.bytesToHexString(mEfCfis));
            }

            if (mEfCff != null) {
                if (enable) {
                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
                            | CFF_UNCONDITIONAL_ACTIVE);
                } else {
                    mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET)
                            | CFF_UNCONDITIONAL_DEACTIVE);
                }

                mFh.updateEFTransparent(
                        EF_CFF_CPHS, mEfCff,
                        obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS));
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            logw("Error saving call forwarding flag to SIM. "
                            + "Probably malformed SIM record", ex);

        }
    }

    /**
     * Called by STK Service when REFRESH is received.
     * @param fileChanged indicates whether any files changed
     * @param fileList if non-null, a list of EF files that changed
     */
    @Override
    public void onRefresh(boolean fileChanged, int[] fileList) {
        if (fileChanged) {
            // A future optimization would be to inspect fileList and
            // only reload those files that we care about.  For now,
            // just re-fetch all SIM records that we cache.
            fetchSimRecords();
        }
    }

    /**
     * {@inheritDoc}
     */
    @UnsupportedAppUsage
    @Override
    public String getOperatorNumeric() {
        String imsi = getIMSI();
        if (imsi == null) {
            log("getOperatorNumeric: IMSI == null");
            return null;
        }
        if (mMncLength == UNINITIALIZED || mMncLength == UNKNOWN) {
            log("getSIMOperatorNumeric: bad mncLength");
            return null;
        }

        // Length = length of MCC + length of MNC
        // length of mcc = 3 (TS 23.003 Section 2.2)
        if (imsi.length() >= 3 + mMncLength) {
            return imsi.substring(0, 3 + mMncLength);
        } else {
            return null;
        }
    }

    // ***** 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) {
                case EVENT_APP_READY:
                    onReady();
                    break;

                case EVENT_APP_LOCKED:
                case EVENT_APP_NETWORK_LOCKED:
                    onLocked(msg.what);
                    break;

                /* 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]"));

                        // Bug #645770 fall back to CPHS
                        // FIXME should use SST to decide

                        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:
                    Rlog.i("ENF", "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);
                        break;
                    } else {
                        mFplmns = parseBcdPlmnList(data, "Forbidden");
                    }
                    if (msg.arg1 == HANDLER_ACTION_SEND_RESPONSE) {
                        if (VDBG) logv("getForbiddenPlmns(): send async response");
                        isRecordLoadResponse = false;
                        Message response = retrievePendingResponseMessage(msg.arg2);
                        if (response != null) {
                            AsyncResult.forMessage(
                                    response, Arrays.copyOf(mFplmns, mFplmns.length), null);
                            response.sendToTarget();
                        } else {
                            loge("Failed to retrieve a response message for FPLMN");
                            break;
                        }
                    }
                    break;

                default:
                    super.handleMessage(msg);   // IccRecords handles generic record load responses
            }
        } 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();
            }
        }
    }

    private class EfPlLoaded implements IccRecordLoaded {
        public String getEfName() {
            return "EF_PL";
        }

        public void onRecordLoaded(AsyncResult ar) {
            mEfPl = (byte[]) ar.result;
            if (DBG) log("EF_PL=" + IccUtils.bytesToHexString(mEfPl));
        }
    }

    private class EfUsimLiLoaded implements IccRecordLoaded {
        public String getEfName() {
            return "EF_LI";
        }

        public void onRecordLoaded(AsyncResult ar) {
            mEfLi = (byte[]) ar.result;
            if (DBG) log("EF_LI=" + IccUtils.bytesToHexString(mEfLi));
        }
    }

    @Override
    protected void handleFileUpdate(int efid) {
        switch(efid) {
            case EF_MBDN:
                mRecordsToLoad++;
                new AdnRecordLoader(mFh).loadFromEF(EF_MBDN, EF_EXT6,
                        mMailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE));
                break;
            case EF_MAILBOX_CPHS:
                mRecordsToLoad++;
                new AdnRecordLoader(mFh).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1,
                        1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE));
                break;
            case EF_CSP_CPHS:
                mRecordsToLoad++;
                log("[CSP] SIM Refresh for EF_CSP_CPHS");
                mFh.loadEFTransparent(EF_CSP_CPHS,
                        obtainMessage(EVENT_GET_CSP_CPHS_DONE));
                break;
            case EF_FDN:
                if (DBG) log("SIM Refresh called for EF_FDN");
                mParentApp.queryFdn();
                mAdnCache.reset();
                break;
            case EF_MSISDN:
                mRecordsToLoad++;
                log("SIM Refresh called for EF_MSISDN");
                new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, getExtFromEf(EF_MSISDN), 1,
                        obtainMessage(EVENT_GET_MSISDN_DONE));
                break;
            case EF_CFIS:
            case EF_CFF_CPHS:
                log("SIM Refresh called for EF_CFIS or EF_CFF_CPHS");
                loadCallForwardingRecords();
                break;
            default:
                // For now, fetch all records if this is not a
                // voicemail number.
                // TODO: Handle other cases, instead of fetching all.
                mAdnCache.reset();
                fetchSimRecords();
                break;
        }
    }

    /**
     * Dispatch 3GPP format message to registrant ({@code GsmCdmaPhone}) to pass to the 3GPP SMS
     * dispatcher for delivery.
     */
    private int dispatchGsmMessage(SmsMessage message) {
        mNewSmsRegistrants.notifyResult(message);
        return 0;
    }

    private void handleSms(byte[] ba) {
        if (ba[0] != 0)
            Rlog.d("ENF", "status : " + ba[0]);

        // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
        // 3 == "received by MS from network; message to be read"
        if (ba[0] == 3) {
            int n = ba.length;

            // Note: Data may include trailing FF's.  That's OK; message
            // should still parse correctly.
            byte[] pdu = new byte[n - 1];
            System.arraycopy(ba, 1, pdu, 0, n - 1);
            SmsMessage message = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);

            dispatchGsmMessage(message);
        }
    }


    private void handleSmses(ArrayList<byte[]> messages) {
        int count = messages.size();

        for (int i = 0; i < count; i++) {
            byte[] ba = messages.get(i);

            if (ba[0] != 0)
                Rlog.i("ENF", "status " + i + ": " + ba[0]);

            // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
            // 3 == "received by MS from network; message to be read"

            if (ba[0] == 3) {
                int n = ba.length;

                // Note: Data may include trailing FF's.  That's OK; message
                // should still parse correctly.
                byte[] pdu = new byte[n - 1];
                System.arraycopy(ba, 1, pdu, 0, n - 1);
                SmsMessage message = SmsMessage.createFromPdu(pdu, SmsConstants.FORMAT_3GPP);

                dispatchGsmMessage(message);

                // 3GPP TS 51.011 v5.0.0 (20011-12)  10.5.3
                // 1 == "received by MS from network; message read"

                ba[0] = 1;

                if (false) { // FIXME: writing seems to crash RdoServD
                    mFh.updateEFLinearFixed(EF_SMS,
                            i, ba, null, obtainMessage(EVENT_MARK_SMS_READ_DONE, i));
                }
            }
        }
    }

    @Override
    protected void onRecordLoaded() {
        // One record loaded successfully or failed, In either case
        // we need to update the recordsToLoad count
        mRecordsToLoad -= 1;
        if (DBG) log("onRecordLoaded " + mRecordsToLoad + " requested: " + mRecordsRequested);

        if (getRecordsLoaded()) {
            onAllRecordsLoaded();
        } else if (getLockedRecordsLoaded() || getNetworkLockedRecordsLoaded()) {
            onLockedAllRecordsLoaded();
        } else if (mRecordsToLoad < 0) {
            loge("recordsToLoad <0, programmer error suspected");
            mRecordsToLoad = 0;
        }
    }

    private void setVoiceCallForwardingFlagFromSimRecords() {
        if (validEfCfis(mEfCfis)) {
            // Refer TS 51.011 Section 10.3.46 for the content description
            mCallForwardingStatus = (mEfCfis[1] & 0x01);
            log("EF_CFIS: callForwardingEnabled=" + mCallForwardingStatus);
        } else if (mEfCff != null) {
            mCallForwardingStatus =
                    ((mEfCff[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE) ?
                            CALL_FORWARDING_STATUS_ENABLED : CALL_FORWARDING_STATUS_DISABLED;
            log("EF_CFF: callForwardingEnabled=" + mCallForwardingStatus);
        } else {
            mCallForwardingStatus = CALL_FORWARDING_STATUS_UNKNOWN;
            log("EF_CFIS and EF_CFF not valid. callForwardingEnabled=" + mCallForwardingStatus);
        }
    }

    private void setSimLanguageFromEF() {
        Resources resource = Resources.getSystem();
        if (resource.getBoolean(com.android.internal.R.bool.config_use_sim_language_file)) {
            setSimLanguage(mEfLi, mEfPl);
        } else {
            if (DBG) log ("Not using EF LI/EF PL");
        }
    }

    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);
        }
    }

    @Override
    protected void onAllRecordsLoaded() {
        if (DBG) log("record load complete");

        setSimLanguageFromEF();
        setVoiceCallForwardingFlagFromSimRecords();

        // Some fields require more than one SIM record to set

        String operator = getOperatorNumeric();
        if (!TextUtils.isEmpty(operator)) {
            log("onAllRecordsLoaded set 'gsm.sim.operator.numeric' to operator='" +
                    operator + "'");
            mTelephonyManager.setSimOperatorNumericForPhone(
                    mParentApp.getPhoneId(), operator);
        } else {
            log("onAllRecordsLoaded empty 'gsm.sim.operator.numeric' skipping");
        }

        String imsi = getIMSI();

        if (!TextUtils.isEmpty(imsi) && imsi.length() >= 3) {
            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");
        }

        setVoiceMailByCountry(operator);
        mLoaded.set(true);
        mRecordsLoadedRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
    }

    //***** Private methods

    private void setVoiceMailByCountry (String spn) {
        if (mVmConfig.containsCarrier(spn)) {
            mIsVoiceMailFixed = true;
            mVoiceMailNum = mVmConfig.getVoiceMailNumber(spn);
            mVoiceMailTag = mVmConfig.getVoiceMailTag(spn);
        }
    }

    /**
     * String[] of forbidden PLMNs will be sent to the Message's handler
     * in the result field of an AsyncResult in the response.obj.
     */
    public void getForbiddenPlmns(Message response) {
        int key = storePendingResponseMessage(response);
        mFh.loadEFTransparent(EF_FPLMN, obtainMessage(
                    EVENT_GET_FPLMN_DONE, HANDLER_ACTION_SEND_RESPONSE, key));
    }

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

    private void onLocked(int msg) {
        if (DBG) log("only fetch EF_LI, EF_PL and EF_ICCID in locked state");
        mLockedRecordsReqReason = msg == EVENT_APP_LOCKED ? LOCKED_RECORDS_REQ_REASON_LOCKED :
                LOCKED_RECORDS_REQ_REASON_NETWORK_LOCKED;

        loadEfLiAndEfPl();

        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
        mRecordsToLoad++;
    }

    private void loadEfLiAndEfPl() {
        if (mParentApp.getType() == AppType.APPTYPE_USIM) {
            mFh.loadEFTransparent(EF_LI,
                    obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfUsimLiLoaded()));
            mRecordsToLoad++;

            mFh.loadEFTransparent(EF_PL,
                    obtainMessage(EVENT_GET_ICC_RECORD_DONE, new EfPlLoaded()));
            mRecordsToLoad++;
        }
    }

    private void loadCallForwardingRecords() {
        mRecordsRequested = true;
        mFh.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE));
        mRecordsToLoad++;
        mFh.loadEFTransparent(EF_CFF_CPHS, obtainMessage(EVENT_GET_CFF_DONE));
        mRecordsToLoad++;
    }

    @UnsupportedAppUsage
    protected void fetchSimRecords() {
        mRecordsRequested = true;

        if (DBG) log("fetchSimRecords " + mRecordsToLoad);

        mCi.getIMSIForApp(mParentApp.getAid(), obtainMessage(EVENT_GET_IMSI_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_ICCID, obtainMessage(EVENT_GET_ICCID_DONE));
        mRecordsToLoad++;

        // FIXME should examine EF[MSISDN]'s capability configuration
        // to determine which is the voice/data/fax line
        new AdnRecordLoader(mFh).loadFromEF(EF_MSISDN, getExtFromEf(EF_MSISDN), 1,
                    obtainMessage(EVENT_GET_MSISDN_DONE));
        mRecordsToLoad++;

        // Record number is subscriber profile
        mFh.loadEFLinearFixed(EF_MBI, 1, obtainMessage(EVENT_GET_MBI_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_AD, obtainMessage(EVENT_GET_AD_DONE));
        mRecordsToLoad++;

        // Record number is subscriber profile
        mFh.loadEFLinearFixed(EF_MWIS, 1, obtainMessage(EVENT_GET_MWIS_DONE));
        mRecordsToLoad++;


        // Also load CPHS-style voice mail indicator, which stores
        // the same info as EF[MWIS]. If both exist, both are updated
        // but the EF[MWIS] data is preferred
        // Please note this must be loaded after EF[MWIS]
        mFh.loadEFTransparent(
                EF_VOICE_MAIL_INDICATOR_CPHS,
                obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE));
        mRecordsToLoad++;

        // Same goes for Call Forward Status indicator: fetch both
        // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred.
        loadCallForwardingRecords();

        getSpnFsm(true, null);

        mFh.loadEFTransparent(EF_SPDI, obtainMessage(EVENT_GET_SPDI_DONE));
        mRecordsToLoad++;

        mFh.loadEFLinearFixed(EF_PNN, 1, obtainMessage(EVENT_GET_PNN_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_SST, obtainMessage(EVENT_GET_SST_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_INFO_CPHS, obtainMessage(EVENT_GET_INFO_CPHS_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_CSP_CPHS,obtainMessage(EVENT_GET_CSP_CPHS_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_GID1, obtainMessage(EVENT_GET_GID1_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_GID2, obtainMessage(EVENT_GET_GID2_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_PLMN_W_ACT, obtainMessage(EVENT_GET_PLMN_W_ACT_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_OPLMN_W_ACT, obtainMessage(EVENT_GET_OPLMN_W_ACT_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_HPLMN_W_ACT, obtainMessage(EVENT_GET_HPLMN_W_ACT_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_EHPLMN, obtainMessage(EVENT_GET_EHPLMN_DONE));
        mRecordsToLoad++;

        mFh.loadEFTransparent(EF_FPLMN, obtainMessage(
                    EVENT_GET_FPLMN_DONE, HANDLER_ACTION_NONE, -1));
        mRecordsToLoad++;

        loadEfLiAndEfPl();

        // XXX should seek instead of examining them all
        if (false) { // XXX
            mFh.loadEFLinearFixedAll(EF_SMS, obtainMessage(EVENT_GET_ALL_SMS_DONE));
            mRecordsToLoad++;
        }

        if (CRASH_RIL) {
            String sms = "0107912160130310f20404d0110041007030208054832b0120"
                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
                         + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
                         + "ffffffffffffffffffffffffffffff";
            byte[] ba = IccUtils.hexStringToBytes(sms);

            mFh.updateEFLinearFixed(EF_SMS, 1, ba, null,
                            obtainMessage(EVENT_MARK_SMS_READ_DONE, 1));
        }
        if (DBG) log("fetchSimRecords " + mRecordsToLoad + " requested: " + mRecordsRequested);
    }

    @Override
    @CarrierNameDisplayConditionBitmask
    public int getCarrierNameDisplayCondition() {
        return mCarrierNameDisplayCondition;
    }

    /**
     * States of Get SPN Finite State Machine which only used by getSpnFsm()
     */
    private enum GetSpnFsmState {
        IDLE,               // No initialized
        @UnsupportedAppUsage
        INIT,               // Start FSM
        @UnsupportedAppUsage
        READ_SPN_3GPP,      // Load EF_SPN firstly
        @UnsupportedAppUsage
        READ_SPN_CPHS,      // Load EF_SPN_CPHS secondly
        @UnsupportedAppUsage
        READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last
    }

    /**
     * Finite State Machine to load Service Provider Name , which can be stored
     * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2)
     *
     * After starting, FSM will search SPN EFs in order and stop after finding
     * the first valid SPN
     *
     * If the FSM gets restart while waiting for one of
     * SPN EFs results (i.e. a SIM refresh occurs after issuing
     * read EF_CPHS_SPN), it will re-initialize only after
     * receiving and discarding the unfinished SPN EF result.
     *
     * @param start set true only for initialize loading
     * @param ar the AsyncResult from loadEFTransparent
     *        ar.exception holds exception in error
     *        ar.result is byte[] for data in success
     */
    @UnsupportedAppUsage
    private void getSpnFsm(boolean start, AsyncResult ar) {
        byte[] data;

        if (start) {
            // Check previous state to see if there is outstanding
            // SPN read
            if (mSpnState == GetSpnFsmState.READ_SPN_3GPP
                    || mSpnState == GetSpnFsmState.READ_SPN_CPHS
                    || mSpnState == GetSpnFsmState.READ_SPN_SHORT_CPHS
                    || mSpnState == GetSpnFsmState.INIT) {
                // Set INIT then return so the INIT code
                // will run when the outstanding read done.
                mSpnState = GetSpnFsmState.INIT;
                return;
            } else {
                mSpnState = GetSpnFsmState.INIT;
            }
        }

        switch(mSpnState){
            case INIT:
                setServiceProviderName(null);

                mFh.loadEFTransparent(EF_SPN,
                        obtainMessage(EVENT_GET_SPN_DONE));
                mRecordsToLoad++;

                mSpnState = GetSpnFsmState.READ_SPN_3GPP;
                break;
            case READ_SPN_3GPP:
                if (ar != null && ar.exception == null) {
                    data = (byte[]) ar.result;

                    // Reference: 3GPP TS 31.102 section 4.2.12 EF_SPN
                    // The first byte is display condition.
                    mCarrierNameDisplayCondition =
                            convertSpnDisplayConditionToBitmask(data[0] & 0xff);

                    setServiceProviderName(IccUtils.adnStringFieldToString(
                                data, 1, data.length - 1));
                    // for card double-check and brand override
                    // we have to do this:
                    final String spn = getServiceProviderName();

                    if (spn == null || spn.length() == 0) {
                        mSpnState = GetSpnFsmState.READ_SPN_CPHS;
                    } else {
                        if (DBG) log("Load EF_SPN: " + spn
                                + " carrierNameDisplayCondition: " + mCarrierNameDisplayCondition);
                        mTelephonyManager.setSimOperatorNameForPhone(
                                mParentApp.getPhoneId(), spn);

                        mSpnState = GetSpnFsmState.IDLE;
                    }
                } else {
                    mSpnState = GetSpnFsmState.READ_SPN_CPHS;
                }

                if (mSpnState == GetSpnFsmState.READ_SPN_CPHS) {
                    mFh.loadEFTransparent( EF_SPN_CPHS,
                            obtainMessage(EVENT_GET_SPN_DONE));
                    mRecordsToLoad++;

                    mCarrierNameDisplayCondition = DEFAULT_CARRIER_NAME_DISPLAY_CONDITION;
                }
                break;
            case READ_SPN_CPHS:
                if (ar != null && ar.exception == null) {
                    data = (byte[]) ar.result;

                    setServiceProviderName(IccUtils.adnStringFieldToString(
                                data, 0, data.length));
                    // for card double-check and brand override
                    // we have to do this:
                    final String spn = getServiceProviderName();

                    if (spn == null || spn.length() == 0) {
                        mSpnState = GetSpnFsmState.READ_SPN_SHORT_CPHS;
                    } else {
                        // Display CPHS Operator Name only when not roaming
                        mCarrierNameDisplayCondition = 0;

                        if (DBG) log("Load EF_SPN_CPHS: " + spn);
                        mTelephonyManager.setSimOperatorNameForPhone(
                                mParentApp.getPhoneId(), spn);

                        mSpnState = GetSpnFsmState.IDLE;
                    }
                } else {
                    mSpnState = GetSpnFsmState.READ_SPN_SHORT_CPHS;
                }

                if (mSpnState == GetSpnFsmState.READ_SPN_SHORT_CPHS) {
                    mFh.loadEFTransparent(
                            EF_SPN_SHORT_CPHS, obtainMessage(EVENT_GET_SPN_DONE));
                    mRecordsToLoad++;
                }
                break;
            case READ_SPN_SHORT_CPHS:
                if (ar != null && ar.exception == null) {
                    data = (byte[]) ar.result;

                    setServiceProviderName(IccUtils.adnStringFieldToString(
                                data, 0, data.length));
                    // for card double-check and brand override
                    // we have to do this:
                    final String spn = getServiceProviderName();

                    if (spn == null || spn.length() == 0) {
                        if (DBG) log("No SPN loaded in either CHPS or 3GPP");
                    } else {
                        // Display CPHS Operator Name only when not roaming
                        mCarrierNameDisplayCondition = 0;

                        if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn);
                        mTelephonyManager.setSimOperatorNameForPhone(
                                mParentApp.getPhoneId(), spn);
                    }
                } else {
                    setServiceProviderName(null);
                    if (DBG) log("No SPN loaded in either CHPS or 3GPP");
                }

                mSpnState = GetSpnFsmState.IDLE;
                break;
            default:
                mSpnState = GetSpnFsmState.IDLE;
        }
    }

    /**
     * Parse TS 51.011 EF[SPDI] record
     * This record contains the list of numeric network IDs that
     * are treated specially when determining SPN display
     */
    private void parseEfSpdi(byte[] data) {
        SimTlv tlv = new SimTlv(data, 0, data.length);

        byte[] plmnEntries = null;

        for ( ; tlv.isValidObject() ; tlv.nextObject()) {
            // Skip SPDI tag, if existant
            if (tlv.getTag() == TAG_SPDI) {
              tlv = new SimTlv(tlv.getData(), 0, tlv.getData().length);
            }
            // There should only be one TAG_SPDI_PLMN_LIST
            if (tlv.getTag() == TAG_SPDI_PLMN_LIST) {
                plmnEntries = tlv.getData();
                break;
            }
        }

        if (plmnEntries == null) {
            return;
        }

        List<String> tmpSpdi = new ArrayList<>(plmnEntries.length / 3);
        for (int i = 0; i + 2 < plmnEntries.length; i += 3) {
            String plmnCode = IccUtils.bcdPlmnToString(plmnEntries, i);
            if (!TextUtils.isEmpty(plmnCode)) {
                log("EF_SPDI PLMN: " + plmnCode);
                tmpSpdi.add(plmnCode);
            }
        }
        mSpdi = (String[]) tmpSpdi.toArray();
    }

    /**
     * convert a byte array of packed plmns to an array of strings
     */
    private String[] parseBcdPlmnList(byte[] data, String description) {
        final int packedBcdPlmnLenBytes = 3;
        log("Received " + description + " PLMNs, raw=" + IccUtils.bytesToHexString(data));
        if (data.length == 0 || (data.length % packedBcdPlmnLenBytes) != 0) {
            loge("Received invalid " + description + " PLMN list");
            return null;
        }
        int numPlmns = data.length / packedBcdPlmnLenBytes;
        int numValidPlmns = 0;
        String[] parsed = new String[numPlmns];
        for (int i = 0; i < numPlmns; i++) {
            parsed[numValidPlmns] = IccUtils.bcdPlmnToString(data, i * packedBcdPlmnLenBytes);
            // we count the valid (non empty) records and only increment if valid
            if (!TextUtils.isEmpty(parsed[numValidPlmns])) numValidPlmns++;
        }
        String[] ret = Arrays.copyOf(parsed, numValidPlmns);
        if (VDBG) logv(description + " PLMNs: " + Arrays.toString(ret));
        return ret;
    }

    /**
     * check to see if Mailbox Number is allocated and activated in CPHS SST
     */
    @UnsupportedAppUsage
    private boolean isCphsMailboxEnabled() {
        if (mCphsInfo == null)  return false;
        return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED );
    }

    @UnsupportedAppUsage
    @Override
    protected void log(String s) {
        Rlog.d(LOG_TAG, "[SIMRecords] " + s);
    }

    @UnsupportedAppUsage
    @Override
    protected void loge(String s) {
        Rlog.e(LOG_TAG, "[SIMRecords] " + s);
    }

    protected void logw(String s, Throwable tr) {
        Rlog.w(LOG_TAG, "[SIMRecords] " + s, tr);
    }

    @UnsupportedAppUsage
    protected void logv(String s) {
        Rlog.v(LOG_TAG, "[SIMRecords] " + s);
    }

    /**
     * Return true if "Restriction of menu options for manual PLMN selection"
     * bit is set or EF_CSP data is unavailable, return false otherwise.
     */
    @Override
    public boolean isCspPlmnEnabled() {
        return mCspPlmnEnabled;
    }

    /**
     * Parse EF_CSP data and check if
     * "Restriction of menu options for manual PLMN selection" is
     * Enabled/Disabled
     *
     * @param data EF_CSP hex data.
     */
    private void handleEfCspData(byte[] data) {
        // As per spec CPHS4_2.WW6, CPHS B.4.7.1, EF_CSP contains CPHS defined
        // 18 bytes (i.e 9 service groups info) and additional data specific to
        // operator. The valueAddedServicesGroup is not part of standard
        // services. This is operator specific and can be programmed any where.
        // Normally this is programmed as 10th service after the standard
        // services.
        int usedCspGroups = data.length / 2;
        // This is the "Service Group Number" of "Value Added Services Group".
        byte valueAddedServicesGroup = (byte)0xC0;

        mCspPlmnEnabled = true;
        for (int i = 0; i < usedCspGroups; i++) {
             if (data[2 * i] == valueAddedServicesGroup) {
                 log("[CSP] found ValueAddedServicesGroup, value " + data[(2 * i) + 1]);
                 if ((data[(2 * i) + 1] & 0x80) == 0x80) {
                     // Bit 8 is for
                     // "Restriction of menu options for manual PLMN selection".
                     // Operator Selection menu should be enabled.
                     mCspPlmnEnabled = true;
                 } else {
                     mCspPlmnEnabled = false;
                     // Operator Selection menu should be disabled.
                     // Operator Selection Mode should be set to Automatic.
                     log("[CSP] Set Automatic Network Selection");
                     mNetworkSelectionModeAutomaticRegistrants.notifyRegistrants();
                 }
                 return;
             }
        }

        log("[CSP] Value Added Service Group (0xC0), not found!");
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("SIMRecords: " + this);
        pw.println(" extends:");
        super.dump(fd, pw, args);
        pw.println(" mVmConfig=" + mVmConfig);
        pw.println(" mCallForwardingStatus=" + mCallForwardingStatus);
        pw.println(" mSpnState=" + mSpnState);
        pw.println(" mCphsInfo=" + mCphsInfo);
        pw.println(" mCspPlmnEnabled=" + mCspPlmnEnabled);
        pw.println(" mEfMWIS[]=" + Arrays.toString(mEfMWIS));
        pw.println(" mEfCPHS_MWI[]=" + Arrays.toString(mEfCPHS_MWI));
        pw.println(" mEfCff[]=" + Arrays.toString(mEfCff));
        pw.println(" mEfCfis[]=" + Arrays.toString(mEfCfis));
        pw.println(" mCarrierNameDisplayCondition=" + mCarrierNameDisplayCondition);
        pw.println(" mSpdi[]=" + mSpdi);
        pw.println(" mUsimServiceTable=" + mUsimServiceTable);
        pw.println(" mGid1=" + mGid1);
        if (mCarrierTestOverride.isInTestMode()) {
            pw.println(" mFakeGid1=" + mCarrierTestOverride.getFakeGid1());
        }
        pw.println(" mGid2=" + mGid2);
        if (mCarrierTestOverride.isInTestMode()) {
            pw.println(" mFakeGid2=" + mCarrierTestOverride.getFakeGid2());
        }
        pw.println(" mPnnHomeName=" + mPnnHomeName);
        if (mCarrierTestOverride.isInTestMode()) {
            pw.println(" mFakePnnHomeName=" + mCarrierTestOverride.getFakePnnHomeName());
        }
        pw.println(" mPlmnActRecords[]=" + Arrays.toString(mPlmnActRecords));
        pw.println(" mOplmnActRecords[]=" + Arrays.toString(mOplmnActRecords));
        pw.println(" mHplmnActRecords[]=" + Arrays.toString(mHplmnActRecords));
        pw.println(" mFplmns[]=" + Arrays.toString(mFplmns));
        pw.println(" mEhplmns[]=" + Arrays.toString(mEhplmns));
        pw.flush();
    }
}
