FileDocCategorySizeDatePackage
UiccCard.javaAPI DocAndroid 5.1 API26559Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony.uicc

UiccCard

public class UiccCard extends Object
{@hide}

Fields Summary
protected static final String
LOG_TAG
protected static final boolean
DBG
private static final String
OPERATOR_BRAND_OVERRIDE_PREFIX
private final Object
mLock
private com.android.internal.telephony.uicc.IccCardStatus.CardState
mCardState
private com.android.internal.telephony.uicc.IccCardStatus.PinState
mUniversalPinState
private int
mGsmUmtsSubscriptionAppIndex
private int
mCdmaSubscriptionAppIndex
private int
mImsSubscriptionAppIndex
private UiccCardApplication[]
mUiccApplications
private android.content.Context
mContext
private com.android.internal.telephony.CommandsInterface
mCi
private com.android.internal.telephony.cat.CatService
mCatService
private com.android.internal.telephony.CommandsInterface.RadioState
mLastRadioState
private UiccCarrierPrivilegeRules
mCarrierPrivilegeRules
private android.os.RegistrantList
mAbsentRegistrants
private android.os.RegistrantList
mCarrierPrivilegeRegistrants
private static final int
EVENT_CARD_REMOVED
private static final int
EVENT_CARD_ADDED
private static final int
EVENT_OPEN_LOGICAL_CHANNEL_DONE
private static final int
EVENT_CLOSE_LOGICAL_CHANNEL_DONE
private static final int
EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE
private static final int
EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE
private static final int
EVENT_SIM_IO_DONE
private static final int
EVENT_CARRIER_PRIVILIGES_LOADED
private int
mPhoneId
protected android.os.Handler
mHandler
Constructors Summary
public UiccCard(android.content.Context c, com.android.internal.telephony.CommandsInterface ci, IccCardStatus ics)


           
        if (DBG) log("Creating");
        mCardState = ics.mCardState;
        update(c, ci, ics);
    
public UiccCard(android.content.Context c, com.android.internal.telephony.CommandsInterface ci, IccCardStatus ics, int phoneId)

        mCardState = ics.mCardState;
        mPhoneId = phoneId;
        update(c, ci, ics);
    
protected UiccCard()

    
Methods Summary
public booleanareCarrierPriviligeRulesLoaded()
Returns true iff carrier priveleges rules are null (dont need to be loaded) or loaded.

        return mCarrierPrivilegeRules == null
            || mCarrierPrivilegeRules.areCarrierPriviligeRulesLoaded();
    
private intcheckIndex(int index, com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType expectedAppType, com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType altExpectedAppType)

        if (mUiccApplications == null || index >= mUiccApplications.length) {
            loge("App index " + index + " is invalid since there are no applications");
            return -1;
        }

        if (index < 0) {
            // This is normal. (i.e. no application of this type)
            return -1;
        }

        if (mUiccApplications[index].getType() != expectedAppType &&
            mUiccApplications[index].getType() != altExpectedAppType) {
            loge("App index " + index + " is invalid since it's not " +
                    expectedAppType + " and not " + altExpectedAppType);
            return -1;
        }

        // Seems to be valid
        return index;
    
protected voidcreateAndUpdateCatService()

        if (mUiccApplications.length > 0 && mUiccApplications[0] != null) {
            // Initialize or Reinitialize CatService
            if (mCatService == null) {
                mCatService = CatService.getInstance(mCi, mContext, this, mPhoneId);
            } else {
                ((CatService)mCatService).update(mCi, mContext, this);
            }
        } else {
            if (mCatService != null) {
                mCatService.dispose();
            }
            mCatService = null;
        }
    
public voiddispose()

        synchronized (mLock) {
            if (DBG) log("Disposing card");
            if (mCatService != null) mCatService.dispose();
            for (UiccCardApplication app : mUiccApplications) {
                if (app != null) {
                    app.dispose();
                }
            }
            mCatService = null;
            mUiccApplications = null;
            mCarrierPrivilegeRules = null;
        }
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        pw.println("UiccCard:");
        pw.println(" mCi=" + mCi);
        pw.println(" mLastRadioState=" + mLastRadioState);
        pw.println(" mCatService=" + mCatService);
        pw.println(" mAbsentRegistrants: size=" + mAbsentRegistrants.size());
        for (int i = 0; i < mAbsentRegistrants.size(); i++) {
            pw.println("  mAbsentRegistrants[" + i + "]="
                    + ((Registrant)mAbsentRegistrants.get(i)).getHandler());
        }
        for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
            pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
                    + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler());
        }
        pw.println(" mCardState=" + mCardState);
        pw.println(" mUniversalPinState=" + mUniversalPinState);
        pw.println(" mGsmUmtsSubscriptionAppIndex=" + mGsmUmtsSubscriptionAppIndex);
        pw.println(" mCdmaSubscriptionAppIndex=" + mCdmaSubscriptionAppIndex);
        pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
        pw.println(" mImsSubscriptionAppIndex=" + mImsSubscriptionAppIndex);
        pw.println(" mUiccApplications: length=" + mUiccApplications.length);
        for (int i = 0; i < mUiccApplications.length; i++) {
            if (mUiccApplications[i] == null) {
                pw.println("  mUiccApplications[" + i + "]=" + null);
            } else {
                pw.println("  mUiccApplications[" + i + "]="
                        + mUiccApplications[i].getType() + " " + mUiccApplications[i]);
            }
        }
        pw.println();
        // Print details of all applications
        for (UiccCardApplication app : mUiccApplications) {
            if (app != null) {
                app.dump(fd, pw, args);
                pw.println();
            }
        }
        // Print details of all IccRecords
        for (UiccCardApplication app : mUiccApplications) {
            if (app != null) {
                IccRecords ir = app.getIccRecords();
                if (ir != null) {
                    ir.dump(fd, pw, args);
                    pw.println();
                }
            }
        }
        // Print UiccCarrierPrivilegeRules and registrants.
        if (mCarrierPrivilegeRules == null) {
            pw.println(" mCarrierPrivilegeRules: null");
        } else {
            pw.println(" mCarrierPrivilegeRules: " + mCarrierPrivilegeRules);
            mCarrierPrivilegeRules.dump(fd, pw, args);
        }
        pw.println(" mCarrierPrivilegeRegistrants: size=" + mCarrierPrivilegeRegistrants.size());
        for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
            pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
                    + ((Registrant)mCarrierPrivilegeRegistrants.get(i)).getHandler());
        }
        pw.flush();
    
protected voidfinalize()

        if (DBG) log("UiccCard finalized");
    
public UiccCardApplicationgetApplication(int family)

        synchronized (mLock) {
            int index = IccCardStatus.CARD_MAX_APPS;
            switch (family) {
                case UiccController.APP_FAM_3GPP:
                    index = mGsmUmtsSubscriptionAppIndex;
                    break;
                case UiccController.APP_FAM_3GPP2:
                    index = mCdmaSubscriptionAppIndex;
                    break;
                case UiccController.APP_FAM_IMS:
                    index = mImsSubscriptionAppIndex;
                    break;
            }
            if (index >= 0 && index < mUiccApplications.length) {
                return mUiccApplications[index];
            }
            return null;
        }
    
public UiccCardApplicationgetApplicationByType(int type)
Returns the SIM application of the specified type.

param
type ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
return
application corresponding to type or a null if no match found

        synchronized (mLock) {
            for (int i = 0 ; i < mUiccApplications.length; i++) {
                if (mUiccApplications[i] != null &&
                        mUiccApplications[i].getType().ordinal() == type) {
                    return mUiccApplications[i];
                }
            }
            return null;
        }
    
public UiccCardApplicationgetApplicationIndex(int index)

        synchronized (mLock) {
            if (index >= 0 && index < mUiccApplications.length) {
                return mUiccApplications[index];
            }
            return null;
        }
    
public com.android.internal.telephony.uicc.IccCardStatus.CardStategetCardState()

        synchronized (mLock) {
            return mCardState;
        }
    
public java.util.ListgetCarrierPackageNamesForIntent(android.content.pm.PackageManager packageManager, android.content.Intent intent)
Exposes {@link UiccCarrierPrivilegeRules.getCarrierPackageNamesForIntent}.

        return mCarrierPrivilegeRules == null ? null :
            mCarrierPrivilegeRules.getCarrierPackageNamesForIntent(
                    packageManager, intent);
    
public intgetCarrierPrivilegeStatus(android.content.pm.Signature signature, java.lang.String packageName)
Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}.

        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName);
    
public intgetCarrierPrivilegeStatus(android.content.pm.PackageManager packageManager, java.lang.String packageName)
Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatus}.

        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName);
    
public intgetCarrierPrivilegeStatusForCurrentTransaction(android.content.pm.PackageManager packageManager)
Exposes {@link UiccCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction}.

        return mCarrierPrivilegeRules == null ?
            TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
            mCarrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(packageManager);
    
public com.android.internal.telephony.cat.CatServicegetCatService()

        return mCatService;
    
public java.lang.StringgetIccId()

        // ICCID should be same across all the apps.
        for (UiccCardApplication app : mUiccApplications) {
            if (app != null) {
                IccRecords ir = app.getIccRecords();
                if (ir != null && ir.getIccId() != null) {
                    return ir.getIccId();
                }
            }
        }
        return null;
    
public intgetNumApplications()

        int count = 0;
        for (UiccCardApplication a : mUiccApplications) {
            if (a != null) {
                count++;
            }
        }
        return count;
    
public java.lang.StringgetOperatorBrandOverride()

        String iccId = getIccId();
        if (TextUtils.isEmpty(iccId)) {
            return null;
        }
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
        return sp.getString(OPERATOR_BRAND_OVERRIDE_PREFIX + iccId, null);
    
public intgetPhoneId()

        return mPhoneId;
    
public com.android.internal.telephony.uicc.IccCardStatus.PinStategetUniversalPinState()

        synchronized (mLock) {
            return mUniversalPinState;
        }
    
public voidiccCloseLogicalChannel(int channel, android.os.Message response)
Exposes {@link CommandsInterface.iccCloseLogicalChannel}

        mCi.iccCloseLogicalChannel(channel,
                mHandler.obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE, response));
    
public voidiccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, java.lang.String pathID, android.os.Message response)
Exposes {@link CommandsInterface.iccIO}

        mCi.iccIO(command, fileID, pathID, p1, p2, p3, null, null,
                mHandler.obtainMessage(EVENT_SIM_IO_DONE, response));
    
public voidiccOpenLogicalChannel(java.lang.String AID, android.os.Message response)
Exposes {@link CommandsInterface.iccOpenLogicalChannel}

        mCi.iccOpenLogicalChannel(AID,
                mHandler.obtainMessage(EVENT_OPEN_LOGICAL_CHANNEL_DONE, response));
    
public voidiccTransmitApduBasicChannel(int cla, int command, int p1, int p2, int p3, java.lang.String data, android.os.Message response)
Exposes {@link CommandsInterface.iccTransmitApduBasicChannel}

        mCi.iccTransmitApduBasicChannel(cla, command, p1, p2, p3,
                data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, response));
    
public voidiccTransmitApduLogicalChannel(int channel, int cla, int command, int p1, int p2, int p3, java.lang.String data, android.os.Message response)
Exposes {@link CommandsInterface.iccTransmitApduLogicalChannel}

        mCi.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3,
                data, mHandler.obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, response));
    
public booleanisApplicationOnIcc(com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType type)

        synchronized (mLock) {
            for (int i = 0 ; i < mUiccApplications.length; i++) {
                if (mUiccApplications[i] != null && mUiccApplications[i].getType() == type) {
                    return true;
                }
            }
            return false;
        }
    
private voidlog(java.lang.String msg)

        Rlog.d(LOG_TAG, msg);
    
private voidloge(java.lang.String msg)

        Rlog.e(LOG_TAG, msg);
    
private voidonCarrierPriviligesLoadedMessage()


       
        synchronized (mLock) {
            mCarrierPrivilegeRegistrants.notifyRegistrants();
        }
    
private voidonIccSwap(boolean isAdded)


        boolean isHotSwapSupported = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_hotswapCapable);

        if (isHotSwapSupported) {
            log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting");
            return;
        }
        log("onIccSwap: isHotSwapSupported is false, prompt for rebooting");

        synchronized (mLock) {
            // TODO: Here we assume the device can't handle SIM hot-swap
            //      and has to reboot. We may want to add a property,
            //      e.g. REBOOT_ON_SIM_SWAP, to indicate if modem support
            //      hot-swap.
            DialogInterface.OnClickListener listener = null;


            // TODO: SimRecords is not reset while SIM ABSENT (only reset while
            //       Radio_off_or_not_available). Have to reset in both both
            //       added or removed situation.
            listener = new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    synchronized (mLock) {
                        if (which == DialogInterface.BUTTON_POSITIVE) {
                            if (DBG) log("Reboot due to SIM swap");
                            PowerManager pm = (PowerManager) mContext
                                    .getSystemService(Context.POWER_SERVICE);
                            pm.reboot("SIM is added.");
                        }
                    }
                }

            };

            Resources r = Resources.getSystem();

            String title = (isAdded) ? r.getString(R.string.sim_added_title) :
                r.getString(R.string.sim_removed_title);
            String message = (isAdded) ? r.getString(R.string.sim_added_message) :
                r.getString(R.string.sim_removed_message);
            String buttonTxt = r.getString(R.string.sim_restart_button);

            AlertDialog dialog = new AlertDialog.Builder(mContext)
            .setTitle(title)
            .setMessage(message)
            .setPositiveButton(buttonTxt, listener)
            .create();
            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            dialog.show();
        }
    
public voidregisterForAbsent(android.os.Handler h, int what, java.lang.Object obj)
Notifies handler of any transition into State.ABSENT

        synchronized (mLock) {
            Registrant r = new Registrant (h, what, obj);

            mAbsentRegistrants.add(r);

            if (mCardState == CardState.CARDSTATE_ABSENT) {
                r.notifyRegistrant();
            }
        }
    
public voidregisterForCarrierPrivilegeRulesLoaded(android.os.Handler h, int what, java.lang.Object obj)
Notifies handler when carrier privilege rules are loaded.

        synchronized (mLock) {
            Registrant r = new Registrant (h, what, obj);

            mCarrierPrivilegeRegistrants.add(r);

            if (areCarrierPriviligeRulesLoaded()) {
                r.notifyRegistrant();
            }
        }
    
public booleanresetAppWithAid(java.lang.String aid)
Resets the application with the input AID. Returns true if any changes were made.

        synchronized (mLock) {
            for (int i = 0; i < mUiccApplications.length; i++) {
                if (mUiccApplications[i] != null && aid.equals(mUiccApplications[i].getAid())) {
                    // Delete removed applications
                    mUiccApplications[i].dispose();
                    mUiccApplications[i] = null;
                    return true;
                }
            }
            return false;
        }
    
private voidsanitizeApplicationIndexes()
This function makes sure that application indexes are valid and resets invalid indexes. (This should never happen, but in case RIL misbehaves we need to manage situation gracefully)

        mGsmUmtsSubscriptionAppIndex =
                checkIndex(mGsmUmtsSubscriptionAppIndex, AppType.APPTYPE_SIM, AppType.APPTYPE_USIM);
        mCdmaSubscriptionAppIndex =
                checkIndex(mCdmaSubscriptionAppIndex, AppType.APPTYPE_RUIM, AppType.APPTYPE_CSIM);
        mImsSubscriptionAppIndex =
                checkIndex(mImsSubscriptionAppIndex, AppType.APPTYPE_ISIM, null);
    
public voidsendEnvelopeWithStatus(java.lang.String contents, android.os.Message response)
Exposes {@link CommandsInterface.sendEnvelopeWithStatus}

        mCi.sendEnvelopeWithStatus(contents, response);
    
public booleansetOperatorBrandOverride(java.lang.String brand)

        log("setOperatorBrandOverride: " + brand);
        log("current iccId: " + getIccId());

        String iccId = getIccId();
        if (TextUtils.isEmpty(iccId)) {
            return false;
        }

        SharedPreferences.Editor spEditor =
                PreferenceManager.getDefaultSharedPreferences(mContext).edit();
        String key = OPERATOR_BRAND_OVERRIDE_PREFIX + iccId;
        if (brand == null) {
            spEditor.remove(key).commit();
        } else {
            spEditor.putString(key, brand).commit();
        }
        return true;
    
public voidunregisterForAbsent(android.os.Handler h)

        synchronized (mLock) {
            mAbsentRegistrants.remove(h);
        }
    
public voidunregisterForCarrierPrivilegeRulesLoaded(android.os.Handler h)

        synchronized (mLock) {
            mCarrierPrivilegeRegistrants.remove(h);
        }
    
public voidupdate(android.content.Context c, com.android.internal.telephony.CommandsInterface ci, IccCardStatus ics)

        synchronized (mLock) {
            CardState oldState = mCardState;
            mCardState = ics.mCardState;
            mUniversalPinState = ics.mUniversalPinState;
            mGsmUmtsSubscriptionAppIndex = ics.mGsmUmtsSubscriptionAppIndex;
            mCdmaSubscriptionAppIndex = ics.mCdmaSubscriptionAppIndex;
            mImsSubscriptionAppIndex = ics.mImsSubscriptionAppIndex;
            mContext = c;
            mCi = ci;

            //update applications
            if (DBG) log(ics.mApplications.length + " applications");
            for ( int i = 0; i < mUiccApplications.length; i++) {
                if (mUiccApplications[i] == null) {
                    //Create newly added Applications
                    if (i < ics.mApplications.length) {
                        mUiccApplications[i] = new UiccCardApplication(this,
                                ics.mApplications[i], mContext, mCi);
                    }
                } else if (i >= ics.mApplications.length) {
                    //Delete removed applications
                    mUiccApplications[i].dispose();
                    mUiccApplications[i] = null;
                } else {
                    //Update the rest
                    mUiccApplications[i].update(ics.mApplications[i], mContext, mCi);
                }
            }

            createAndUpdateCatService();

            // Reload the carrier privilege rules if necessary.
            log("Before privilege rules: " + mCarrierPrivilegeRules + " : " + mCardState);
            if (mCarrierPrivilegeRules == null && mCardState == CardState.CARDSTATE_PRESENT) {
                mCarrierPrivilegeRules = new UiccCarrierPrivilegeRules(this,
                        mHandler.obtainMessage(EVENT_CARRIER_PRIVILIGES_LOADED));
            } else if (mCarrierPrivilegeRules != null && mCardState != CardState.CARDSTATE_PRESENT) {
                mCarrierPrivilegeRules = null;
            }

            sanitizeApplicationIndexes();

            RadioState radioState = mCi.getRadioState();
            if (DBG) log("update: radioState=" + radioState + " mLastRadioState="
                    + mLastRadioState);
            // No notifications while radio is off or we just powering up
            if (radioState == RadioState.RADIO_ON && mLastRadioState == RadioState.RADIO_ON) {
                if (oldState != CardState.CARDSTATE_ABSENT &&
                        mCardState == CardState.CARDSTATE_ABSENT) {
                    if (DBG) log("update: notify card removed");
                    mAbsentRegistrants.notifyRegistrants();
                    mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_REMOVED, null));
                } else if (oldState == CardState.CARDSTATE_ABSENT &&
                        mCardState != CardState.CARDSTATE_ABSENT) {
                    if (DBG) log("update: notify card added");
                    mHandler.sendMessage(mHandler.obtainMessage(EVENT_CARD_ADDED, null));
                }
            }
            mLastRadioState = radioState;
        }