android Sim卡鎖定 pin解鎖流程學習

1.Android自帶的pin解鎖部份在framework/base/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java

Sim鎖定後開機,會調用這個類,show出“請輸入pin”的解鎖介面,輸入pin密碼後,點擊“ok”,調用checkPin( )

通過啓動一個線程CheckSimPin來調用TelephonyManagersupplyPin()接口,並註冊一個類似於Callback的虛函數onSimLockChangedResponse()並實現之,這樣當supplyPin()調用返回時,觸發該Callback函數。

    privatevoidcheckPin() {

         //…….//

        new CheckSimPin(mPinText.getText().toString()) {

           void onSimLockChangedResponse(boolean success) {

               if (mSimUnlockProgressDialog != null) {

                   mSimUnlockProgressDialog.hide();

                }

               if (success) {

                   mUpdateMonitor.reportSimPinUnlocked();

                   mCallback.goToUnlockScreen();

                }else {

                   mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);

                   mPinText.setText("");

                   mEnteredDigits = 0;

                }

               mCallback.pokeWakelock();

            }

        }.start();

    }

 

    privateabstractclassCheckSimPinextends Thread {

        privatefinal StringmPin;

        protected CheckSimPin(String pin) {

           mPin = pin;

        }

        abstractvoid onSimLockChangedResponse(boolean success);

        @Override

        publicvoid run() {

           try {

               finalboolean result = ITelephony.Stub.asInterface(ServiceManager

                        .checkService("phone")).supplyPin(mPin);//result返回的值來自PhoneInterfaceManager

                post(new Runnable() {

                   publicvoid run() {

                        onSimLockChangedResponse(result);

                    }

                });

            }catch (RemoteException e) {

                post(new Runnable() {

                   publicvoid run() {

                        onSimLockChangedResponse(false);

                    }

                });

            }

        }

    }

2.supplyPin()接口的具體實現在PhoneInterfaceManager中,代碼位置在packages/apps/Phone/src/com/android/phone/PhoneInterfaceManager.java。

首先創建一個線程並啓動來維護一個Handler用於接收RIL上來的消息(SUPPLY_PIN_COMPLETE)。隨後調用IccCard的supplyPin()方法並將Handler註冊上去,此後一直wait,直到Hander收到指定消息後將其喚醒返回,並將操作結果傳給其調用者。

    publicboolean supplyPin(String pin) {

        enforceModifyPermission();

        final CheckSimPin checkSimPin =new CheckSimPin(mPhone.getIccCard());

        checkSimPin.start();

        return checkSimPin.checkPin(pin);

    }

privatestaticclass CheckSimPin extends Thread {

 

        privatefinal IccCardmSimCard;

        privatebooleanmDone = false;

        privatebooleanmResult = false;

        // For replies from SimCard interface

        private HandlermHandler;

        // For async handler to identify request type

        privatestaticfinalintSUPPLY_PIN_COMPLETE = 100;

        public CheckSimPin(IccCard simCard) {

           mSimCard = simCard;

        }

        @Override

        publicvoid run() {

            Looper.prepare();

           synchronized (CheckSimPin.this) {

               mHandler =new Handler() {

                   @Override

                   publicvoid handleMessage(Message msg) {

                       AsyncResult ar = (AsyncResult) msg.obj;

                       switch (msg.what) {

                           caseSUPPLY_PIN_COMPLETE:

                                Log.d(LOG_TAG,"SUPPLY_PIN_COMPLETE");

                               synchronized (CheckSimPin.this) {

                                   mResult = (ar.exception ==null);//ar.exceptionnull,則說明驗證通過mResult = true

                                   mDone =true;

                                    CheckSimPin.this.notifyAll();

                                }

                               break;

                        }

                    }

                };

                CheckSimPin.this.notifyAll();

            }

            Looper.loop();

        }

 

        synchronizedboolean checkPin(String pin) {

 

           while (mHandler == null) {

               try {

                    wait();

                }catch (InterruptedException e) {

                    Thread.currentThread().interrupt();

                }

            }

            Message callback = Message.obtain(mHandler,SUPPLY_PIN_COMPLETE);

            mSimCard.supplyPin(pin, callback);

 

           while (!mDone) {

               try {

                    Log.d(LOG_TAG,"wait for done");

                    wait();

                }catch (InterruptedException e) {

                   // Restore the interrupted status

                    Thread.currentThread().interrupt();

                }

            }

            Log.d(LOG_TAG,"done");

            Log.d(LOG_TAG,"mResult : "+mResult);

           returnmResult

        }

    }

3.接下來IccCard.javaframeworks/base/telephony/java/com/android/internal/telephony/IccCard.java

調用RIL.javasupplyPin()見第4條。

創建一個Handler來接受EVENT_PINPUK_DONE,當Handler接收到EVENT_PINPUK_DONE

    publicvoid supplyPin (String pin, Message onComplete) {

        mPhone.mCM.supplyIccPin(pin,mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));

        Log.i("IccCard!!!","supplyPin");

    }

protected HandlermHandler =new Handler() {

        @Override

        publicvoid handleMessage(Message msg){

           AsyncResult ar;

           int serviceClassX;

            serviceClassX =CommandsInterface.SERVICE_CLASS_VOICE +

                           CommandsInterface.SERVICE_CLASS_DATA +

                           CommandsInterface.SERVICE_CLASS_FAX;

 

           if (!mPhone.mIsTheCurrentActivePhone) {

                Log.e(mLogTag,"Received message " + msg +"[" + msg.what

                        +"] while being destroyed. Ignoring.");

               return;

            }

           switch (msg.what) {

               //………//

               caseEVENT_PINPUK_DONE:

 

                    ar = (AsyncResult)msg.obj;

                   // TODO should abstract these exceptions

                   AsyncResult.forMessage(((Message)ar.userObj)).exception

                                                        = ar.exception;

                   mPhone.mCM.getIccCardStatus(

                        obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj));

                   break;

               caseEVENT_REPOLL_STATUS_DONE:

                  

                    ar = (AsyncResult)msg.obj;

                    getIccCardStatusDone(ar);

                    ((Message)ar.userObj).sendToTarget();

                   break;

                //…………………….//

               default:

                    Log.e(mLogTag,"[IccCard] Unknown Event " + msg.what);

            }

        }

    };

4. frameworks/base/telephony/java/com/android/internal/telephony/RIL.java中的supplyIccPin()

   @Overridepublicvoid

    supplyIccPin(String pin, Message result) {

        supplyIccPinForApp(pin,null, result);

    }

    @Overridepublicvoid

    supplyIccPinForApp(String pin, String aid, Message result) {

        //Note: This RIL request has not been renamed to ICC,

        //       but this request is also valid for SIM and RUIM

        RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result);

        if (RILJ_LOGD) riljLog(rr.serialString() + "> " +requestToString(rr.mRequest));

        rr.mp.writeInt(2);

        rr.mp.writeString(pin);

        rr.mp.writeString(aid);

        send(rr);//通過socket rild發送 RIL_REQUEST_ENTER_SIM_PIN請求

    }




轉自:http://blog.csdn.net/k1102k27/article/details/6804368



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章