Android 7.0 UICC 分析

卧疾丰暇豫,翰墨时间作。这篇文章主要讲述Android 7.0 UICC 分析相关的知识,希望能为你提供帮助。
本文讲解UiccCard类
/frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCard.java
UICCController 类的onGetIccCardStatusDone() 方法,根据获取的SIM状态信息IccCardStatus 创建或更新UiccCard 对象;

private synchronized void onGetIccCardStatusDone(AsyncResult ar, Integer index) { ....... IccCardStatus status = (IccCardStatus)ar.result; if (mUiccCards[index] == null) { //Create new card mUiccCards[index] = new UiccCard(mContext, mCis[index], status, index); } else { //Update already existing card mUiccCards[index].update(mContext, mCis[index] , status); } ....... }

 
UiccCard 类的构造方法,同样会调用update() 方法更新SIM 卡状态信息;
public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) { mCardState = ics.mCardState; mPhoneId = phoneId; update(c, ci, ics); }

UiccCard 类的 update() 方法:
1、根据IccCardStatus 参数在mUiccApplication 列表中匹配UiccCardApplication  对象,通过UiccCardApplication 类的update() 方法更新,否则创建一个UiccCardApplication 对象;
2、调用createAndUpdateCatService() 方法创建或更新CatService 对象;
3、获取Radiostate状态,更新CardState,发出SIM卡插拔消息;
public void update(Context c, CommandsInterface ci, IccCardStatus ics) { ........ //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); //调用UiccCardApplication.java } }createAndUpdateCatService(); //CatService .......... 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; } }

 
【Android 7.0 UICC 分析】createAndUpdateCatService() 方法,创建或更新CatService:
protected void createAndUpdateCatService() { 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; } }


消息EVENT_CARD_REMOVED、 EVENT_CARD_ADDED 在UiccCard 类的handleMessage()方法中处理:
protected Handler mHandler = new Handler() { @Override public void handleMessage(Message msg){ switch (msg.what) { case EVENT_CARD_REMOVED: onIccSwap(false); break; case EVENT_CARD_ADDED: onIccSwap(true); break; ......... } } };

onIccSwap() 方法,判断是否共卡座,如果是直接返回,否则调用promptForRestart():
private void onIccSwap(boolean isAdded) {boolean isHotSwapSupported = mContext.getResources().getBoolean( 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"); promptForRestart(isAdded); }

promptForRestart() 方法,切换sim卡,弹出提示框:
private void promptForRestart(boolean isAdded) { synchronized (mLock) { final Resources res = mContext.getResources(); final String dialogComponent = res.getString( R.string.config_iccHotswapPromptForRestartDialogComponent); if (dialogComponent != null) { Intent intent = new Intent().setComponent(ComponentName.unflattenFromString( dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .putExtra(EXTRA_ICC_CARD_ADDED, isAdded); try { mContext.startActivity(intent); return; } catch (ActivityNotFoundException e) { loge("Unable to find ICC hotswap prompt for restart activity: " + e); } }// 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(); } }

 


    推荐阅读