Sim Lock —— 手机Network锁

前记:

        因为别人疑问和期望,而对Sim Lock发生兴趣,期望可以帮别人解Sim Lock 锁。·未有发现,不知何时会再拿起,故作整理。

问题:

        对于手机Network锁——Sim Lock,指定的运营商的Sim Card有效,其它运营商的Sim Card无效。那各种手机水货是怎么解决Sim Lock问题,使得可以在大陆流行?

       有一种说法为:找到手机Sim Lock写入位置,然后擦除。

条件:Android 4.0.4 定制后的framework code. 非原始code.

研究过程:

 一. Sim Lock 界面

     1.  Sim Lock界面是一个Dialog, 由 IccDepersonalizationPanel 产生。

         IccDepersonalizationPanel.java 位于 packages/apps/phone 中。

         用Eclipse 观察 Sim Lock 界面,查看这个界面是谁产生的,布局如何。 通过 Hierarchy View 发现有一个id为perso_subtype_text的Text View. 对frameworks 和 Phone 的code 搜索,发现Sim Lock界面由 Sim_ndp.xml定义,由 IccDepersonalizationPanel.java 产生。

     2. 对Unlock Button进行监听

         //调用IccCard中supplyDepersonalization,检验输入的PIN,通过mHandler的handleMessage处理检验结果

         mPhone.getIccCard().supplyDepersonalization(pin, mPersoSubtype, Message.obtain(mHandler,EVENT_ICC_DEPERSONALIZATION_RESULT));

         //显示IN_PROGRESS过程信息

           displayStatus(IN_PROGRESS);

      3. mHandler

     private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == EVENT_ICC_DEPERSONALIZATION_RESULT) {
                AsyncResult res = (AsyncResult) msg.obj;
                if (res.exception != null) {
                    if (DBG) log("De-Personalization request failure.");
                    displayStatus(ERROR); // PIN输入错误
                    postDelayed(new Runnable() { // 重新显示Sim Lock输入界面
                                    public void run() {
                                        hideAlert();
                                        mPinEntry.getText().clear();
                                        mPinEntry.requestFocus(); 
                                    }
                                }, 3000);
                } else {
                    if (DBG) log("De-Personalization success.");
                    displayStatus(SUCCESS); // PIN 输入正确
                    postDelayed(new Runnable() { // 3秒后关闭Sim Lock Dialog
                                    public void run() {
                                        dismiss();
                                    }
                                }, 3000);
                }
            }
        }
    };

 

二. Sim Lock 产生过程

     1. PhoneApp.java 的onCreate()中通过IccCard注册监听

        PhoneApp.java 位于 packages/apps/phone 中。在PhoneApp.java 的 onCreate() 中注册监听。

           //通过IccCard的registerForPersoLocked注册监听,通过mHandler处理监听结果

            // register for ICC status
            IccCard sim = phone.getIccCard();
            if (sim != null) {
                if (VDBG) Log.v(LOG_TAG, "register for ICC status");
                sim.registerForPersoLocked(mHandler, EVENT_PERSO_LOCKED, null);
            }

         Note: 没有sim card时,不进行Sim Lock监听.

     2. mHandler处理Sim Lock消息EVENT_PERSO_LOCKED

          case EVENT_PERSO_LOCKED:
              if (mContext.getResources().getBoolean(R.bool.ignore_sim_perso_locked_events)) {
                   // Some products don't have the concept of a "SIM network lock"
                   Log.i(LOG_TAG, "Ignoring EVENT_PERSO_LOCKED event; " + "not showing 'SIM network unlock' PIN entry screen");
              } else {
                    // Normal case: show the "perso unlock" PIN entry screen.
                    // The user won't be able to do anything else until
                    // they enter a valid PIN.
                    AsyncResult ar = (AsyncResult) msg.obj;
                     if (ar.result != null) {
                          initIccDepersonalizationPanel(ar); //初始化Sim Lock的界面
                      }
                }
            break;

     3. initIccDepersonalizationPanel 初始化Sim Lock类IccDepersonalizationPanel, 并Show Sim Lock Dialog.

    void initIccDepersonalizationPanel(AsyncResult ar) {
        Log.i(LOG_TAG, "show sim depersonal panel");
        int subtype = (Integer)ar.result;
        IccDepersonalizationPanel dpPanel =
                new IccDepersonalizationPanel(PhoneApp.getInstance(), subtype);
        dpPanel.show();
    }

 

三. IccCard 处理Sim Lock过程

   1. IccCard.java、IccCardProxy.java

       IccCard 是接口基类;IccCardProxy 是IccCard的实现类,并继承于Handler。都位于:

        \frameworks\base\telephony\java\com\android\internal\telephony

   2. IccCardProxy中的registerForPersoLocked
    public void registerForPersoLocked(Handler h, int what, Object obj) {

        //打包成登记者,加入SimLock监听队列
        Registrant r = new Registrant (h, what, obj);
        mPersoLockedRegistrants.add(r);

        //检查目前的IccCard状态
        if (getState() == State.PERSO_LOCKED) {
            r.notifyRegistrant(new AsyncResult(null, mPersoSubState.ordinal(), null));
        }
    }

   3. IccCardProxy中的supplyDepersonalization

    /**
     * Use invokeDepersonalization from PhoneBase class instead.
     */
    public void supplyDepersonalization(String pin, int type, Message onComplete) {
        if (mUiccApplication != null) {//双卡处理
            mUiccApplication.supplyDepersonalization(pin, type, onComplete); 
        } else if (onComplete != null) {//单卡处理
            Exception e = new RuntimeException("CommandsInterface is not set.");
            AsyncResult.forMessage(onComplete).exception = e;
            onComplete.sendToTarget();
            return;
        }
    }

   4. IccCardProxy接受到Sim Lock消息,并进行处理

            case EVENT_PERSO_LOCKED:
                mPersoSubState = mUiccApplication.getPersoSubState();
                mPersoLockedRegistrants.notifyRegistrants((AsyncResult)msg.obj); // 通知Sim Lock注册队列中的所有登记者.
                setExternalState(State.PERSO_LOCKED); //设置Sim card状态
                break;

   5. setExternalState设置Sim card状态,把Sim Card状态保存在系统属性中,并粘性广播Sim Card状态。

     protected void setExternalState(State newState, boolean override) {
        if (!override && newState == mExternalState) {
            return;
        }
        mExternalState = newState; // 设置Sim card状态
        SystemProperties.set(PROPERTY_SIM_STATE, mExternalState.toString()); //把Sim Card状态保存到系统属性中
        broadcastIccStateChangedIntent(mExternalState.getIntentString(), //粘性广播Sim card状态.
                                       mExternalState.getReason());
        // TODO: Need to notify registrants for other states as well.
        if ( State.ABSENT == mExternalState) {
            mAbsentRegistrants.notifyRegistrants();
        }
    }

   Note:  可见有三种方式获得Sim Card状态

                    i) 通过IccCardProxy的getState() 可以获得Sim Card状态。

                    ii) 通过读取系统属性获得Sim Card状态: SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE);

                    iii) 通过监听粘性广播TelephonyIntents.ACTION_SIM_STATE_CHANGED 来获得Sim Card状态。

                         粘性广播的意义在于持久保留,不会被系统删除,所有的receiver都能接受。无时间限制。

 

归纳总结:

     Sim Lock产生过程:

           PhoneApp通过IccCard注册监听 --> IccCard 收到Message, 通知登记者(Registrant)  --> PhoneApp根据收到的Message显示相应界面

     Sim Lock检验过程:

           Sim Lock界面接受输入PIN --> IccCard检查PIN,并返回结果 --> Sim Lock界面收到Message,显示处理结果

 

待解决问题:

 1. IccCardProxy是怎么获得相关Message通知的?

     有人说IccCardProxy与RIL有关联,但是这关联不知体现在什么地方、什么方式上?

 2. 获得相关Sim Lock PIN后,IccCardProxy是怎么匹配处理并返回结果的?

     在supplyDepersonalization 中没发现。

 3. 流程图

 

 

 

 

 

 

你可能感兴趣的:(android系统)