SubId

Android O

SubId,即SIM卡id,此id为数据库中的"_id"字段,从1开始。

每当我们向手机插入一张SIM卡,此卡的相关记录就会被保存到数据库,而其记录的"_id"字段则被用作SubId。

若SIM卡之前已插入过手机,则再次插入时就会直接从数据库中去读取原来的SubId。

DummySubId:当无卡或卡未加载完成时,我们无法获得真正的SubId,只能得到一个Dummy值,为"-2 - SlotId"。

8369077b6e6defefdb3ed7a52df41b4bdae.jpg
SubId的添加:
当SIM LOADED后,会发送android.intent.action.internal_sim_state_changed的广播,
SubscriptionInfoUpdater.sReceiver会收到并进行处理。

private final BroadcastReceiver sReceiver = new  BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        ......
        logd("Action: " + action);
        ......
            } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(simStatus)) {
                sendMessage(obtainMessage(EVENT_SIM_LOADED, slotIndex, -1));
            } else {
        ......
}

public void handleMessage(Message msg) {
        ......
       case EVENT_SIM_LOADED:
            handleSimLoaded(msg.arg1);
            break;
        ......
}


protected void handleSimLoaded(int slotId) {
    logd("handleSimLoaded: slotId: " + slotId);
    ......
    if (isAllIccIdQueryDone()) {
        updateSubscriptionInfoByIccId();
        ......
}


synchronized private void updateSubscriptionInfoByIccId() {
    logd("updateSubscriptionInfoByIccId:+ Start");
    ......
    // We only clear the slot-to-sub map when one/some SIM was removed. Note this is a
    // workaround for some race conditions that the empty map was accessed while we are
    // rebuilding the map.
    if (SubscriptionController.getInstance().getActiveSubIdList().length > insertedSimCount) {
        SubscriptionController.getInstance().clearSubInfo();
    }
    ......
    //check if the inserted SIM is new SIM
    int nNewCardCount = 0;
    int nNewSimStatus = 0;
    for (int i = 0; i < PROJECT_SIM_NUM; i++) {
        if (mInsertSimState[i] == SIM_NOT_INSERT) {
            logd("updateSubscriptionInfoByIccId: No SIM inserted in slot " + i + " this time");
        } else {
            if (mInsertSimState[i] > 0) {
                //some special SIMs may have the same IccIds, add suffix to distinguish them
                //FIXME: addSubInfoRecord can return an error.
                mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i]
                        + Integer.toString(mInsertSimState[i]), i);
                logd("SUB" + (i + 1) + " has invalid IccId");
            } else /*if (sInsertSimState[i] != SIM_NOT_INSERT)*/ {
                mSubscriptionManager.addSubscriptionInfoRecord(mIccId[i], i);
            }
            ......

    ......
}


SubscriptionManager.java

public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
    ......
        ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
        if (iSub != null) {
            // FIXME: This returns 1 on success, 0 on error should should we return it?
            iSub.addSubInfoRecord(iccId, slotIndex);
    ......
}

 

SubscriptionController.java

public int addSubInfoRecord(String iccId, int slotIndex) {
    if (DBG) logdl("[addSubInfoRecord]+ iccId:" + SubscriptionInfo.givePrintableIccid(iccId) +
            " slotIndex:" + slotIndex);
    ......
        // 根据iccId从数据库读取SIM卡信息
        ContentResolver resolver = mContext.getContentResolver();
        Cursor cursor = resolver.query(SubscriptionManager.CONTENT_URI,
                new String[]{SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
                        SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.NAME_SOURCE},
                SubscriptionManager.ICC_ID + "=?", new String[]{iccId}, null);

        boolean setDisplayName = false;
        try {
            if (cursor == null || !cursor.moveToFirst()) {
                // 此SIM卡之前未插入过,然后我们就会先插入一条新的空记录
                setDisplayName = true;
                Uri uri = insertEmptySubInfoRecord(iccId, slotIndex);
                if (DBG) logdl("[addSubInfoRecord] New record created: " + uri);
            } else {
                // 此SIM卡之前插入过,就直接读取其SubId
                int subId = cursor.getInt(0);
                ......
                if (value.size() > 0) {
                    resolver.update(SubscriptionManager.CONTENT_URI, value,
                            SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID +
                                    "=" + Long.toString(subId), null);

                    // Refresh the Cache of Active Subscription Info List
                    refreshCachedActiveSubscriptionInfoList();
        ......
        }

        // 然后再将SubId加入sSlotIndexToSubId中
        cursor = resolver.query(SubscriptionManager.CONTENT_URI, null,
                SubscriptionManager.SIM_SLOT_INDEX + "=?",
                new String[] {String.valueOf(slotIndex)}, null);
        try {
            ......
                        sSlotIndexToSubId.put(slotIndex, subId);
            ......
        }
        ......
}


public int clearSubInfo() {
    ......
        sSlotIndexToSubId.clear();
    ......
}


SubId的删除:
流程类似,也会走到updateSubscriptionInfoByIccId(),然后clearSubInfo。

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/igiantpanda/blog/1859153

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值