对UiccController 的认识

 UiccController 是对SIM卡管理的控制器,它通过 UiccCard 来更新SIM卡的信息。
  1.UiccController 注册了两个监听器,来监听RIL的消息。分别监听 UNSOL_RESPONSE_RADIO_STATE_CHANGED 和 RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,当radio 和 sim卡状态发生变化时,它会第一时间得到消息。
  2. 开机后,RIL 会上报 Radio off,然后上报 radio on,一旦 radio on ,mOnRegistrants.notifyRegistrants(),这个语句就会被调用,具体实现如下,
protected void setRadioState(RadioState newState) {
            .....
            mRadioStateChangedRegistrants.notifyRegistrants();

            if (mState.isAvailable() && !oldState.isAvailable()) {
                Log.d(LOG_TAG,"Notifying: radio available");
                mAvailRegistrants.notifyRegistrants();
                onRadioAvailable();
            }

            if (!mState.isAvailable() && oldState.isAvailable()) {
                Log.d(LOG_TAG,"Notifying: radio not available");
                mNotAvailRegistrants.notifyRegistrants();
            }

            if (mState.isOn() && !oldState.isOn()) {
                Log.d(LOG_TAG,"Notifying: Radio On");
                mOnRegistrants.notifyRegistrants();
            }

            if ((!mState.isOn() || !mState.isAvailable())
                && !((!oldState.isOn() || !oldState.isAvailable()))
            ) {
                Log.d(LOG_TAG,"Notifying: radio off or not available");
                mOffOrNotAvailRegistrants.notifyRegistrants();
            }
        }
    }
   notify 后,会通知相关对象,相关对象就会进行处理,UiccController 就是其中一个对象,处理事件 EVENT_ICC_STATUS_CHANGED.
因为 UiccController的构造方法中存在如下代码。
    private UiccController(Context c, CommandsInterface[] ci) {
        if (DBG) log("Creating UiccController");
        mContext = c;
        mCi = ci;
        for (int i = 0; i < mCi.length; i++) {
            Integer index = new Integer(i);
            //意思是说 RIL 中收到 RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 消息,notify 所有监听器后,UiccController 就会处理 EVENT_ICC_STATUS_CHANGED 事件
            mCi[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, index);   
            mCi[i].registerForOff(this, EVENT_RADIO_OFF, index);
            // TODO remove this once modem correctly notifies the unsols
            // 意思是说 RIL 中收到 Radio ON 消息,notify 所有的监听器后,UiccController 就会处理 EVENT_ICC_STATUS_CHANGED 事件。
            mCi[i].registerForOn(this, EVENT_ICC_STATUS_CHANGED, index);
        }
    }
    同样 当SIM卡状态发生变化后,上报RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED后,UiccController 也将处理事件 Event_ICC_STATUS_CHANGED,所以当手机信号不好或者SIM卡本身的状态发生变化的时候,消息都会集中到UiccConroller这里进行处理,然后传播到所有对SIM卡数据感兴趣的地方。UiccController 就是SIM卡管理的最为核心的类。
   <1> 通知 UiccController,UiccControl 处理EVENT_ICC_STATUS_CHANGED的消息
 case EVENT_ICC_STATUS_CHANGED:
                    if (DBG) log("Received EVENT_ICC_STATUS_CHANGED, calling getIccCardStatus");
                    mCi.getIccCardStatus(obtainMessage(EVENT_GET_ICC_STATUS_DONE));
                    break;
  <2> UiccControl 发出 RIL_REQUEST_GET_SIM_STATUS的请求,获取SIM卡的状态信息。
  case EVENT_GET_ICC_STATUS_DONE:
                    if (DBG) log("Received EVENT_GET_ICC_STATUS_DONE");
                    AsyncResult ar = (AsyncResult)msg.obj;
                    onGetIccCardStatusDone(ar);
                    break;
 onGetIccCardStatusDone:
       IccCardStatus status = (IccCardStatus)ar.result;
        if (mUiccCard == null) {
            //Create new card
            mUiccCard = new UiccCard(mContext, mCi, status);
        } else {
            //Update already existing card
            mUiccCard.update(mContext, mCi , status);
        }
        if (DBG) log("Notifying IccChangedRegistrants");
        mIccChangedRegistrants.notifyRegistrants();
   <3> RIL 返回SIM卡的状态信息,UiccControl 处理返回的SIM卡的信息,创建 UiccCard和 UiccCardApplication 对象。具体的实现过程如下
主要是在 UiccCard 的update 方法当中
public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
        synchronized (mLock) {
            if (mDestroyed) {
                loge("Updated after destroyed! Fix me!");
                return;
            }
            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);
                }
            }

            if (mUiccApplications.length > 0 && mUiccApplications[0] != null) {
                // Initialize or Reinitialize CatService
                mCatService = CatService.getInstance(mCi,
                                                     mContext,
                                                     this);
            } else {
                if (mCatService != null) {
                    mCatService.dispose();
                }
                mCatService = 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;
        }
    }
  3.系统中其他对象对SIM卡的状态,SIM卡的数据信息很感兴趣,他们通过UiccController来监听SIM卡的状态变化。所以当UiccCard更新完成后,它就通知 ServiceStateTracker(Gsm or Cdma),IccCardProxy,DataConnectionTracker,PhoneBase,SIM卡的状态已经发生了变化。
DataConnectionTracker
GsmDataConnectionTracker
 protected void onUpdateIcc() {
        if (mUiccController == null ) {
            return;
        }

        IccRecords newIccRecords = mUiccController.getIccRecords(UiccController.APP_FAM_3GPP);

        IccRecords r = mIccRecords.get();
        if (r != newIccRecords) {
            if (r != null) {
                log("Removing stale icc objects.");
                r.unregisterForRecordsLoaded(this);
                mIccRecords.set(null);
            }
            if (newIccRecords != null) {
                log("New records found");
                mIccRecords.set(newIccRecords);
                newIccRecords.registerForRecordsLoaded(
                        this, DctConstants.EVENT_RECORDS_LOADED, null);
            }
        }
    }
  更新所持有的mIccRecords 对象的数据
IccCardProxy
  private void updateIccAvailability() {
        synchronized (mLock) {
            UiccCard newCard = mUiccController.getUiccCard();
            CardState state = CardState.CARDSTATE_ABSENT;
            UiccCardApplication newApp = null;
            IccRecords newRecords = null;
            if (newCard != null) {
                state = newCard.getCardState();
                newApp = newCard.getApplication(mCurrentAppType);
                if (newApp != null) {
                    newRecords = newApp.getIccRecords();
                }
            }

            if (mIccRecords != newRecords || mUiccApplication != newApp || mUiccCard != newCard) {
                if (DBG) log("Icc changed. Reregestering.");
                unregisterUiccCardEvents();
                mUiccCard = newCard;
                mUiccApplication = newApp;
                mIccRecords = newRecords;
                registerUiccCardEvents();
            }

            updateExternalState();
        }
    }
   更新所持有的 mUiccCard,mUiccApplication,mIccRecords 对象。
    当sim卡状态变化时,会发出广播
   private void broadcastIccStateChangedIntent(String value, String reason) {
        synchronized (mLock) {
            if (mQuietMode) {
                log("QuietMode: NOT Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
                        + " reason " + reason);
                return;
            }

            Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
            intent.putExtra(PhoneConstants.PHONE_NAME_KEY, "Phone");
            intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE, value);
            intent.putExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON, reason);

            if (DBG) log("Broadcasting intent ACTION_SIM_STATE_CHANGED " +  value
                    + " reason " + reason);
            ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE,
                    UserHandle.USER_ALL);
        }
    }
   如果应用程序或者系统服务对SIM卡的状态有兴趣,那么可以监听这个广播
PhoneBase
GsmPhone
protected void onUpdateIccAvailability() {
        if (mUiccController == null ) {
            return;
        }

        UiccCardApplication newUiccApplication =
                mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);

        UiccCardApplication app = mUiccApplication.get();
        if (app != newUiccApplication) {
            if (app != null) {
                if (LOCAL_DEBUG) log("Removing stale icc objects.");
                if (mIccRecords.get() != null) {
                    unregisterForSimRecordEvents();
                    mSimPhoneBookIntManager.updateIccRecords(null);
                }
                mIccRecords.set(null);
                mUiccApplication.set(null);
            }
            if (newUiccApplication != null) {
                if (LOCAL_DEBUG) log("New Uicc application found");
                mUiccApplication.set(newUiccApplication);
                mIccRecords.set(newUiccApplication.getIccRecords());
                registerForSimRecordEvents();
                mSimPhoneBookIntManager.updateIccRecords(mIccRecords.get());
            }
        }
    }
更新所持有的mUiccApplication,mIccRecords,mSimPhoneBookIntManager 对象。
ServiceStateTracker
GsmServiceStateTracker
protected void onUpdateIccAvailability() {
        if (mUiccController == null ) {
            return;
        }

        UiccCardApplication newUiccApplication =
                mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP);

        if (mUiccApplcation != newUiccApplication) {
            if (mUiccApplcation != null) {
                log("Removing stale icc objects.");
                mUiccApplcation.unregisterForReady(this);
                if (mIccRecords != null) {
                    mIccRecords.unregisterForRecordsLoaded(this);
                }
                mIccRecords = null;
                mUiccApplcation = null;
            }
            if (newUiccApplication != null) {
                log("New card found");
                mUiccApplcation = newUiccApplication;
                mIccRecords = mUiccApplcation.getIccRecords();
                mUiccApplcation.registerForReady(this, EVENT_SIM_READY, null);
                if (mIccRecords != null) {
                    mIccRecords.registerForRecordsLoaded(this, EVENT_SIM_RECORDS_LOADED, null);
                }
            }
        }
    }

更新 所持有的mIccRecords,mUiccApplication,等对象。

与UiccController 相关的数据流程如下图所示

对UiccController 的认识_第1张图片

你可能感兴趣的:(对UiccController 的认识)