Android11.0(R) 预留清空锁屏密码接口
前言
出廠的設(shè)備有些客戶喜歡設(shè)置鎖屏密碼,無奈記性不好,忘記密碼后就只能恢復(fù)出廠或者重新刷機(jī)了,啊這客戶肯定不接受的。
為了防止客戶逼逼賴賴,我們就未雨綢繆,給它加個清除接口。
先說結(jié)論,系統(tǒng)鎖屏密碼數(shù)據(jù)庫存儲位于 /data/system/locksettings.db
經(jīng)過測試 O 版本直接刪除 locksettings.db 就已經(jīng)達(dá)到要求
測試 Q、R 版本直接刪除 locksettings.db 后,系統(tǒng)鎖屏界面確實(shí)沒了,但一直卡在安卓正在啟動界面了,
無法進(jìn)入桌面,進(jìn)入設(shè)置中查看 Launcher3 應(yīng)用丟了,目測此路不通。
那就曲線救國去研究 Settings 中是如何驗(yàn)證密碼并取消密碼的。
Settings 中各版本存儲密碼傳遞對象,已圖案密碼為例 ConfirmLockPattern.java
O、P 版本 密碼 String intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, LockPatternUtils.patternToString(pattern));
Q 版本 密碼 Byte[] intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, LockPatternUtils.patternToByteArray(pattern));
R 版本 密碼 LockscreenCredential intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
framework 往下加解密流程可參考這篇 AndroidQ 鎖屏密碼驗(yàn)證流程之GateKeeper解析
解決思路
一:找到 Settings 中與用戶交互設(shè)置鎖屏密碼核心代碼,將繪制圖案或者密碼字符保存起來(數(shù)據(jù)庫、prop、ContentProvider等)
二:增加清除接口(AIDL、廣播、ContentResolver監(jiān)聽等)
三:取出用戶設(shè)置密碼轉(zhuǎn)換為 framework 所需要 LockscreenCredential 對象
四:移除密碼
上代碼
4.1、找到鎖屏圖案保存核心代碼
vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\password\ChooseLockPattern.java
protected LockPatternView.OnPatternListener mChooseNewLockPatternListener =new LockPatternView.OnPatternListener() {....public void onPatternDetected(List<LockPatternView.Cell> pattern) {if (mUiStage == Stage.NeedToConfirm || mUiStage == Stage.ConfirmWrong) {if (mChosenPattern == null) throw new IllegalStateException("null chosen pattern in stage 'need to confirm");try (LockscreenCredential confirmPattern =LockscreenCredential.createPattern(pattern)) {if (mChosenPattern.equals(confirmPattern)) {//20200903 cczheng add save lockdata startmScreenLockHelper.saveCurrentLockData(pattern);//20200903 cczheng add save lockdata endupdateStage(Stage.ChoiceConfirmed);} else {updateStage(Stage.ConfirmWrong);}}} else if (mUiStage == Stage.Introduction || mUiStage == Stage.ChoiceTooShort){if (pattern.size() < LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {updateStage(Stage.ChoiceTooShort);} else {mChosenPattern = LockscreenCredential.createPattern(pattern);updateStage(Stage.FirstChoiceValid);}} else {throw new IllegalStateException("Unexpected stage " + mUiStage + " when "+ "entering the pattern.");}}mChosenPattern 第一次繪制圖案密碼,confirmPattern 第二次繪制圖案密碼,兩次一致設(shè)置成功,
就地保存圖案密碼。圖案密碼九宮格每個點(diǎn) Cell 對應(yīng)一個 Row, 一個 Column,實(shí)際規(guī)則如下
(0,0) (0,1) (0,2)
(1,0) (1,1) (1,2)
(2,0) (2,1) (2,2)
最終畫線將每一個 cell 添加到集合中。
實(shí)際圖案密碼對象 LockscreenCredential.createPattern(pattern);
4.2、找到PIN碼和密碼保存核心代碼
vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\password\ChooseLockPassword.java
public void handleNext() {if (mSaveAndFinishWorker != null) return;// TODO(b/120484642): This is a point of entry for passwords from the UIfinal Editable passwordText = mPasswordEntry.getText();if (TextUtils.isEmpty(passwordText)) {return;}mChosenPassword = mIsAlphaMode ? LockscreenCredential.createPassword(passwordText): LockscreenCredential.createPin(passwordText);if (mUiStage == Stage.Introduction) {if (validatePassword(mChosenPassword)) {mFirstPassword = mChosenPassword;mPasswordEntry.setText("");updateStage(Stage.NeedToConfirm);} else {mChosenPassword.zeroize();}} else if (mUiStage == Stage.NeedToConfirm) {if (mChosenPassword.equals(mFirstPassword)) {//20200903 cczheng add save lockdata startmScreenLockHelper.saveCurrentLockData(mIsAlphaMode, passwordText.toString());//20200903 cczheng add save lockdata endstartSaveAndFinish();} else {CharSequence tmp = mPasswordEntry.getText();if (tmp != null) {Selection.setSelection((Spannable) tmp, 0, tmp.length());}updateStage(Stage.ConfirmWrong);mChosenPassword.zeroize();}}}mIsAlphaMode 用來區(qū)分是 PIN 碼還是密碼
實(shí)際密碼對象 LockscreenCredential.createPassword(passwordText)
實(shí)際PIN碼對象 LockscreenCredential.createPin(passwordText)
4.3、找到移除密碼核心代碼
設(shè)置完鎖屏密碼后再次進(jìn)入鎖屏選擇頁面,此時需要驗(yàn)證剛剛設(shè)置密碼,驗(yàn)證成功后才能進(jìn)入鎖屏選擇界面。
驗(yàn)證成功就獲取到了 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD, pattern);
這個很關(guān)鍵,一會需要用它來移除鎖屏密碼
vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\password\ChooseLockGeneric.java
void updateUnlockMethodAndFinish(int quality, boolean disabled, boolean chooseLockSkipped) {.....if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {// Clearing of user biometrics when screen lock is cleared is done at// LockSettingsService.removeBiometricsForUser().if (mUserPassword != null) {// No need to call setLockCredential if the user currently doesn't// have a passwordmChooseLockSettingsHelper.utils().setLockCredential(LockscreenCredential.createNone(), mUserPassword, mUserId);}mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);getActivity().setResult(Activity.RESULT_OK);finish();}}關(guān)鍵方法就兩個
setLockCredential(新密碼,舊密碼,用戶id)
setLockScreenDisabled(移除密碼,用戶id)
4.4、造數(shù)據(jù)移除密碼
package com.android.settings.password;import android.content.Context; import android.util.Log; import android.os.SystemProperties; import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.LockPatternView; import com.android.internal.widget.LockPatternView.Cell; import com.android.internal.widget.LockscreenCredential;import java.util.ArrayList; import java.util.Collections; import java.util.List;public class ScreenLockHelper{private static final String TAG = "ScreenLockHelper";//value startwith //pt&xxxx LockPattern//pn&xxxx LockPin//ps&xxxx LockPasswordprivate final String KEY = "persist.android.screen.lock";private final String HEAD_PAT = "pt&";private final String HEAD_PIN = "pn&";private final String HEAD_PWD = "ps&";private Context mContext;private LockPatternUtils mLockPatternUtils;public ScreenLockHelper(Context context) {mContext = context;mLockPatternUtils = new LockPatternUtils(context);}public void saveCurrentLockData(boolean mIsPwd, String pwd) {pwd = (mIsPwd ? HEAD_PWD : HEAD_PIN) + pwd;SystemProperties.set(KEY, pwd);}public void saveCurrentLockData(List<LockPatternView.Cell> pattern) {String pwd = HEAD_PAT;StringBuilder builder = new StringBuilder();builder.append(pwd);for (int i=0; i<pattern.size(); i++) {LockPatternView.Cell cell = pattern.get(i);builder.append(cell.getRow());builder.append("*");builder.append(cell.getColumn());if (i != pattern.size() - 1) {builder.append("+");}Log.i(TAG,"cell="+cell.toString());}pwd = builder.toString();SystemProperties.set(KEY, pwd);}public void clearScreenLock() {LockscreenCredential emptyCredential = LockscreenCredential.createNone();LockscreenCredential savedCredential;String pwdValue = SystemProperties.get(KEY, "");if (pwdValue.startsWith(HEAD_PIN)) {savedCredential = LockscreenCredential.createPin(pwdValue.substring(3));}else if (pwdValue.startsWith(HEAD_PWD)) {savedCredential = LockscreenCredential.createPassword(pwdValue.substring(3));}else if (pwdValue.startsWith(HEAD_PAT)) {pwdValue = pwdValue.substring(3);List<LockPatternView.Cell> pattern = new ArrayList<LockPatternView.Cell>();String[] cellArray = pwdValue.split("\\+");for (String cellStr : cellArray) {String[] cell = cellStr.split("\\*");pattern.add(Cell.of(Integer.parseInt(cell[0]), Integer.parseInt(cell[1])));}savedCredential = LockscreenCredential.createPattern(pattern);}else{savedCredential = LockscreenCredential.createNone();}mLockPatternUtils.setLockCredential(emptyCredential, savedCredential, 0);mLockPatternUtils.setLockScreenDisabled(true, 0);} }總結(jié)
以上是生活随笔為你收集整理的Android11.0(R) 预留清空锁屏密码接口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试基础理论体系学习5-静态测试的理
- 下一篇: matlab做能耗制动,能耗制动matl