1.Android自帶的pin解鎖部份在framework/base/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
Sim鎖定后開機,會調用這個類,show出“請輸入pin”的解鎖介面,輸入pin密碼后,點擊“ok”,調用checkPin( )
通过启动一个线程CheckSimPin来调用TelephonyManager的supplyPin()接口,并注册一个类似于Callback的虚函数onSimLockChangedResponse()并实现之,这样当supplyPin()调用返回时,触发该Callback函数。
privatevoidcheckPin(){
//…….//
newCheckSimPin(mPinText.getText().toString()) {
voidonSimLockChangedResponse(booleansuccess) {
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();
}
privateabstractclassCheckSimPinextendsThread {
privatefinalStringmPin;
protectedCheckSimPin(String pin) {
mPin= pin;
}
abstractvoidonSimLockChangedResponse(booleansuccess);
@Override
publicvoidrun() {
try{
finalbooleanresult = ITelephony.Stub.asInterface(ServiceManager
.checkService("phone")).supplyPin(mPin);//result返回的值來自PhoneInterfaceManager中
post(newRunnable() {
publicvoidrun() {
onSimLockChangedResponse(result);
}
});
}catch(RemoteException e) {
post(newRunnable() {
publicvoidrun() {
onSimLockChangedResponse(false);
}
});
}
}
}
2.supplyPin()接口的具体实现在PhoneInterfaceManager中,代码位置在packages/apps/Phone/src/com/android/phone/PhoneInterfaceManager.java。
首先创建一个线程并启动来维护一个Handler用于接收RIL上来的消息(SUPPLY_PIN_COMPLETE)。随后调用IccCard的supplyPin()方法并将Handler注册上去,此后一直wait,直到Hander收到指定消息后将其唤醒返回,并将操作结果传给其调用者。
publicbooleansupplyPin(String pin) {
enforceModifyPermission();
finalCheckSimPin checkSimPin =newCheckSimPin(mPhone.getIccCard());
checkSimPin.start();
returncheckSimPin.checkPin(pin);
}
privatestaticclassCheckSimPinextendsThread {
privatefinalIccCardmSimCard;
privatebooleanmDone=false;
privatebooleanmResult=false;
// For replies from SimCard interface
privateHandlermHandler;
// For async handler to identify request type
privatestaticfinalintSUPPLY_PIN_COMPLETE= 100;
publicCheckSimPin(IccCard simCard) {
mSimCard= simCard;
}
@Override
publicvoidrun() {
Looper.prepare();
synchronized(CheckSimPin.this) {
mHandler=newHandler() {
@Override
publicvoidhandleMessage(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.exception為null,則說明驗證通過mResult = true
mDone=true;
CheckSimPin.this.notifyAll();
}
break;
}
}
};
CheckSimPin.this.notifyAll();
}
Looper.loop();
}
synchronizedbooleancheckPin(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.java在frameworks/base/telephony/java/com/android/internal/telephony/IccCard.java
調用RIL.java的supplyPin()見第4條。
創建一個Handler來接受EVENT_PINPUK_DONE,當Handler接收到EVENT_PINPUK_DONE,
publicvoidsupplyPin (String pin, Message onComplete) {
mPhone.mCM.supplyIccPin(pin,mHandler.obtainMessage(EVENT_PINPUK_DONE, onComplete));
Log.i("IccCard!!!","supplyPin");
}
protectedHandlermHandler=newHandler() {
@Override
publicvoidhandleMessage(Message msg){
AsyncResult ar;
intserviceClassX;
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;
//TODOshould 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