• 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;
            }
        }

    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.");  //SIM卡上电重启
                            }
                        }
                    }
    
                };
    
                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();  //SIM卡弹出提示框
            }
        }
  • 相关阅读:
    MongoDb
    js暴露内部方法属性等
    JS闭包
    k8s设计模式
    scrum
    死锁
    Linux下安装php 扩展fileinfo
    linux中whereis、which、find、location的区别和用法
    Linux 命令学习记录
    windows 下 redis 的安装及使用
  • 原文地址:https://www.cnblogs.com/kaifyou/p/6172234.html
Copyright © 2020-2023  润新知