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() {
//…….//
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.exception為null,則說明驗證通過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.java在frameworks/base/telephony/java/com/android/internal/telephony/IccCard.java
調用RIL.java的supplyPin()見第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