SIM卡加载

SIM卡加载流程

先了解一下,双卡双待,首先Android手机一般都是双卡的情况

每一张卡都会创建一个Phone,比如两张卡 就会创建两个Phone

一,初始化流程,注册流程

首先来看一下DcTracker构造函数

    //***** Constructor
    public DcTracker(Phone phone, int transportType) {
        super();
        //每个Phone对象有自己DcTracker
        //每个DcTracker加载各自卡可用的APN
        mPhone = phone;
        if (DBG) log("DCT.constructor");
        mTransportType = transportType;
        mDataServiceManager = new DataServiceManager(phone, transportType);

        mResolver = mPhone.getContext().getContentResolver();
        //监听卡载入
        mUiccController = UiccController.getInstance();
        mUiccController.registerForIccChanged(this, DctConstants.EVENT_ICC_CHANGED, null);
        mAlarmManager =
                (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
        mCm = (ConnectivityManager) mPhone.getContext().getSystemService(
                Context.CONNECTIVITY_SERVICE);


        mDataEnabledSettings = new DataEnabledSettings(phone);

        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
        mAutoAttachOnCreation.set(sp.getBoolean(Phone.DATA_DISABLED_ON_BOOT_KEY, false));
        //监听卡信息变化
        mSubscriptionManager = SubscriptionManager.from(mPhone.getContext());
        mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);

        HandlerThread dcHandlerThread = new HandlerThread("DcHandlerThread");
        dcHandlerThread.start();
        Handler dcHandler = new Handler(dcHandlerThread.getLooper());
        mDcc = DcController.makeDcc(mPhone, this, mDataServiceManager, dcHandler);
        mDcTesterFailBringUpAll = new DcTesterFailBringUpAll(mPhone, dcHandler);

        mDataConnectionTracker = this;
        registerForAllEvents();
        update();
        //监听APN数据库变化
        mApnObserver = new ApnChangeObserver();
        phone.getContext().getContentResolver().registerContentObserver(
                Telephony.Carriers.CONTENT_URI, true, mApnObserver);
        //初始化不同APN类型对应的网络能力
        initApnContexts();

        for (ApnContext apnContext : mApnContexts.values()) {
            // Register the reconnect and restart actions.
            filter = new IntentFilter();
            filter.addAction(INTENT_RECONNECT_ALARM + '.' + apnContext.getApnType());
            mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
        }

        // 默认情况下,将紧急APN添加到APN设置列表,以在不存在情况下支持EPDN
        initEmergencyApnSetting();
        addEmergencyApnSetting();

        mProvisionActionName = "com.android.internal.telephony.PROVISION" + phone.getPhoneId();

        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
        registerSettingsObserver();
    }

 

这一块可能需要看一些注册,监听卡载入(UiccController.getInstance())。还有监听卡的变换, mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener); 

二,插卡加载

在PhoneFactory.java中初始化UiccController对象,通过ProxyController.getInstance(....) 注册。

当插入卡的情况下会触发UiccController,EVENT_ICC_STATUS_CHANGED。

UiccController.java
 

    @Override
    public void handleMessage (Message msg) {
        synchronized (mLock) {
            //1.首先从Message中取出PhoneId
            Integer phoneId = getCiIndex(msg);
		}
		switch (msg.what) {
                case EVENT_ICC_STATUS_CHANGED:  //如果拔卡和插卡就会触发到这个位置
                    Log.v("InitSimCartId","事件注册 : 对ICC状态的任何更改触发  EVENT_ICC_STATUS_CHANGED ");

                    if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
                    //2.查询当前SIM卡的状态
                    mCis[phoneId].getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE,
                            phoneId));
                    break;
					....
					.....
					.....
				}
		}

向RIL查询当前SIM卡的状态,EVENT_GET_ICC_STATUS_DONE

通过RIL交互机制。

UiccController.java

    /**
     * 实例化UiccCard对象
     *当查询SIM卡的状态完毕后,先从result中解析出IccCardStatus,
     * 依据IccCardStatus来创建UiccCard对象, 一个UiccCard 对象代表着一张SIM卡;
     * 如果UiccCard对象已存在就直接调它的update()方法更新UiccCard的信息。
     */
    private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) {
        if (ar.exception != null) {
            Rlog.e(LOG_TAG,"Error getting ICC status. "
                    + "RIL_REQUEST_GET_ICC_STATUS should "
                    + "never return an error", ar.exception);
            return;
        }
        if (!isValidPhoneIndex(index)) {
            Rlog.e(LOG_TAG,"onGetIccCardStatusDone: invalid index : " + index);
            return;
        }

        IccCardStatus status = (IccCardStatus)ar.result;

        sLocalLog.log("onGetIccCardStatusDone: phoneId " + index + " IccCardStatus: " + status);

        int slotId = status.physicalSlotIndex;
        if (VDBG) log("onGetIccCardStatusDone: phoneId " + index + " physicalSlotIndex " + slotId);
        if (slotId == INVALID_SLOT_ID) {
            slotId = index;
        }
        mPhoneIdToSlotId[index] = slotId;

        if (VDBG) logPhoneIdToSlotIdMapping();
        //创建或更新UiccCard
        if (mUiccSlots[slotId] == null) {
            if (VDBG) {
                log("Creating mUiccSlots[" + slotId + "]; mUiccSlots.length = "
                        + mUiccSlots.length);
            }
            //Create new card 调的是4个参数的构造方法
            mUiccSlots[slotId] = new UiccSlot(mContext, true);
        }
        //最后调用的还是update方法
        mUiccSlots[slotId].update(mCis[index], status, index);

        if (DBG) log("Notifying IccChangedRegistrants");
        //通知监听UiccController的监听者
        mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, index, null));
    }

DcTracker.java

    @Override
    public void handleMessage (Message msg) {
        if (VDBG) log("handleMessage msg=" + msg);
		....
		......
        switch (msg.what) {
		    ....
		    .....
		    case DctConstants.EVENT_ICC_CHANGED: {
                onUpdateIcc();
                break;
            }
			....
		}
	}

进入onUpdateIcc();其中会注册IccRecord ,观察卡的信息是否载入成功

    private void onUpdateIcc() {
        if (mUiccController == null ) {
            return;
        }

        IccRecords newIccRecords = mPhone.getIccRecords();

        IccRecords r = mIccRecords.get();
        if (r != newIccRecords) {
            //移除对旧有信息的记录
            if (r != null) {
                log("Removing stale icc objects.");
                r.unregisterForRecordsLoaded(this);
                mIccRecords.set(null);
            }
            if (newIccRecords != null) {
                if (mSubscriptionManager.isActiveSubId(mPhone.getSubId())) {
                    log("New records found.");
                    mIccRecords.set(newIccRecords);
                    //向IccRecord注册,观察卡信息是否载入完成
                    //收到通知后,DcTracker将发送EVENT_RECORDS_LOADED信息给自己处理
                    newIccRecords.registerForRecordsLoaded(
                            this, DctConstants.EVENT_RECORDS_LOADED, null);
                }
            } else {
                onSimNotReady();
            }
        }
    }

这里主要处理注册消息。如果卡载入成功会触发DcTracker中的EVENT_RECORDS_LOADED

    @Override
    public void handleMessage (Message msg) {
        if (VDBG) log("handleMessage msg=" + msg);

        switch (msg.what) {
            case DctConstants.EVENT_RECORDS_LOADED:
                mSimRecords = mPhone.getSIMRecords();
                if ((mIccRecords.get() instanceof RuimRecords) && (mSimRecords != null)) {
                    mSimRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
                } else {
                    onRecordsLoaded();
                }
                break;
        }
    }

这里会进入onRecordsLoaded()

    void onRecordsLoaded() {
        // If onRecordsLoadedOrSubIdChanged() is not called here, it should be called on
        // onSubscriptionsChanged() when a valid subId is available.
        int subId = mPhone.getSubId();
        if (mSubscriptionManager.isActiveSubId(subId)) {
            onRecordsLoadedOrSubIdChanged();
        } else {
            log("Ignoring EVENT_RECORDS_LOADED as subId is not valid: " + subId);
        }
    }
   protected void onRecordsLoadedOrSubIdChanged() {
        if (DBG) log("onRecordsLoadedOrSubIdChanged: createAllApnList");
        mAutoAttachOnCreationConfig = mPhone.getContext().getResources()
                .getBoolean(com.android.internal.R.bool.config_auto_attach_data_on_creation);
        //
        createAllApnList();
        //设置初始使用的APN
        setInitialAttachApn();
        if (mPhone.mCi.getRadioState().isOn()) {
            if (DBG) log("onRecordsLoadedOrSubIdChanged: notifying data availability");
            notifyOffApnsOfAvailability(Phone.REASON_SIM_LOADED);
        }
        setupDataOnConnectableApns(Phone.REASON_SIM_LOADED);
    }

猜你喜欢

转载自blog.csdn.net/qq_35427437/article/details/107239962
今日推荐