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 String mPin;

        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 IccCard mSimCard;

        privatebooleanmDone = false;

        privatebooleanmResult = false;

        // For replies from SimCard interface

        private Handler mHandler;

        // 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 Handler mHandler = 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 请求

    }

後面的c实现部分,目前沒有去看。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页