您的位置:首页 > 移动开发 > Android开发

android Sim卡锁定 pin解锁流程学习

2012-05-25 20:34 309 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: