插入sim卡弹出密码锁定窗口过程
如图,开了pin码的sim卡插入手机后会弹出要输入pin码的锁定窗口
这个Android 12中大致的过程可以从logcat的打印看出一些
这个界面主要由2个部分组成,上部分KeyguardMessageArea, 下部分KeyguardSimPinView
顶部文本显示定制
“请输入 SIM 1 PIN,您还可尝试3次”这个文本显示与下方的pin码输入窗口不是一个窗口,是分开控制的。通过搜索上面的中文提示文本,对应的UI或代码
frameworks/base/packages/SystemUI/res-unisoc/values-zh-rCN/strings_ex.xml
<plurals name="kg_password_wrong_pin_code_multi">
<item quantity="one">SIM <xliff:g id="carrier" example="CARD 1">%1$s</xliff:g> PIN 码不正确,您还有 <xliff:g id="number">%2$d</xliff:g> 次尝试机会。如果仍不正确,则需要联系运营商帮您解锁设备。</item>
<item quantity="other">SIM <xliff:g id="carrier" example="CARD 1">%1$s</xliff:g> PIN 码不正确,您还有 <xliff:g id="number">%2$d</xliff:g> 次尝试机会。</item>
</plurals>
<plurals name="kg_password_default_pin_message_multi">
<item quantity="one">请输入 SIM <xliff:g id="carrier" example="CARD 1">%1$s</xliff:g> PIN,您还可以尝试 <xliff:g id="number">%2$d</xliff:g> 次。如果仍不正确,则需要联系运营商帮您解锁设备。</item>
<item quantity="other">请输入 SIM <xliff:g id="carrier" example="CARD 1">%1$s</xliff:g> PIN,您还可以尝试 <xliff:g id="number">%2$d</xliff:g> 次。</item>
</plurals>
默认显示在最顶端的是这个kg_password_default_pin_message_multi
其是在
frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
中控制显示的,
动态变化sim卡输入还剩的次数的文本由以下函数返回
private String getPinPasswordErrorMessage(int attemptsRemaining, boolean isDefault) {
String displayMessage;
int msgId;
if (attemptsRemaining == 0) {
displayMessage = mView.getResources().getString(
R.string.kg_password_wrong_pin_code_pukked);
} else if (attemptsRemaining > 0) {
int count = TelephonyManager.getDefault().getSimCount();
if (count < 2) {
msgId = isDefault ? R.plurals.kg_password_default_pin_message :
R.plurals.kg_password_wrong_pin_code;
displayMessage = mView.getResources()
.getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
} else {
msgId = isDefault ? R.plurals.kg_password_default_pin_message_multi :
R.plurals.kg_password_wrong_pin_code_multi;
int phoneId = SubscriptionManager.getPhoneId(mSubId);
SubscriptionInfo info = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(mSubId);
Log.d(LOG_TAG, "phoneId : " + phoneId + "; mSubId : " + mSubId + "; info : " + info);
if (info!= null && !SubscriptionManager.isValidPhoneId(phoneId)) {
phoneId = info.getSimSlotIndex();
Log.d(LOG_TAG, "SubscriptionInfo:"+info.toString() + "; phoneId : " + phoneId);
}
displayMessage = mView.getResources().getQuantityString(msgId,
attemptsRemaining, phoneId + 1, attemptsRemaining);
}
} else {
msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
displayMessage = mView.getResources().getString(msgId);
}
if (KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId)) {
displayMessage = mView.getResources()
.getString(R.string.kg_sim_lock_esim_instructions, displayMessage);
}
if (DEBUG) {
Log.d(LOG_TAG, "getPinPasswordErrorMessage: attemptsRemaining="
+ attemptsRemaining + " displayMessage=" + displayMessage);
}
return displayMessage;
}
此文本是由mMessageAreaController通过调用sendMessage来显示的
mMessageAreaController.setMessage(getPinPasswordErrorMessage(result.getAttemptsRemaining(), false));
mMessageAreaController的创建
KeyguardPatternViewController.java:206: mMessageAreaControllerFactory = messageAreaControllerFactory;
KeyguardPatternViewController.java:208: mMessageAreaController = mMessageAreaControllerFactory.create(kma);
KeyguardAbsKeyInputViewController.java:91: mMessageAreaController = messageAreaControllerFactory.create(kma);
KeyguardAbsKeyInputViewController.java:99: mMessageAreaController.init();
KeyguardAbsKeyInputViewController.java:144: mMessageAreaController.reloadColors();
protected KeyguardPatternViewController(KeyguardPatternView view,
KeyguardUpdateMonitor keyguardUpdateMonitor,
SecurityMode securityMode,
LockPatternUtils lockPatternUtils,
KeyguardSecurityCallback keyguardSecurityCallback,
LatencyTracker latencyTracker,
FalsingCollector falsingCollector,
EmergencyButtonController emergencyButtonController,
KeyguardMessageAreaController.Factory messageAreaControllerFactory) {
super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
mFalsingCollector = falsingCollector;
mEmergencyButtonController = emergencyButtonController;
mMessageAreaControllerFactory = messageAreaControllerFactory;
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
mMessageAreaController = mMessageAreaControllerFactory.create(kma);
mLockPatternView = mView.findViewById(R.id.lockPatternView);
}
protected KeyguardAbsKeyInputViewController(T view,
KeyguardUpdateMonitor keyguardUpdateMonitor,
SecurityMode securityMode,
LockPatternUtils lockPatternUtils,
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, FalsingCollector falsingCollector,
EmergencyButtonController emergencyButtonController) {
super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
mFalsingCollector = falsingCollector;
mEmergencyButtonController = emergencyButtonController;
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
mMessageAreaController = messageAreaControllerFactory.create(kma);
}
这个显示区域KeyguardMessageArea是由findSecurityMessageDisplay创建的
frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardMessageArea.java
public static KeyguardMessageArea findSecurityMessageDisplay(View v) {
KeyguardMessageArea messageArea = v.findViewById(R.id.keyguard_message_area);
if (messageArea == null) {
messageArea = v.getRootView().findViewById(R.id.keyguard_message_area);
}
if (messageArea == null) {
throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
}
return messageArea;
}
由此定位到xml中的id: R.id.keyguard_message_area
安卓12中,密码输入框与顶部文本KeyguardMessageArea是两块UI
如下修改可以隐藏掉顶部文本区域,让密码输入框最大化
diff --git a/frameworks/base/packages/SystemUI/res-keyguard/values/dimens.xml b/frameworks/base/packages/SystemUI/res-keyguard/values/dimens.xml
index cfc9fbba4f0..7cbe0a266a0 100644
--- a/frameworks/base/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/frameworks/base/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -37,8 +37,8 @@
<dimen name="keyguard_password_height">80dp</dimen>
<!-- Margin around the various security views -->
- <dimen name="keyguard_security_view_top_margin">8dp</dimen>
- <dimen name="keyguard_security_view_lateral_margin">20dp</dimen>
+ <dimen name="keyguard_security_view_top_margin">0dp</dimen>
+ <dimen name="keyguard_security_view_lateral_margin">0dp</dimen>
修改密码按键背景与样式
frameworks/base/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@+id/background">
<shape>
<solid android:color="?android:attr/colorControlNormal" />
<corners android:radius="10dp" />
</shape>
</item>
</ripple>
其中color可以修改背景色,radius修改圆角。
密码按键文本颜色修改
frameworks/base/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
public void reloadColors() {
int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
.getDefaultColor();
int klondikeColor = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary)
.getDefaultColor();
mDigitText.setTextColor(textColor);
mKlondikeText.setTextColor(klondikeColor);
if (mAnimator != null) mAnimator.reloadColors(getContext());
}
密码输入框样式
frameworks/base/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
文本颜色
/**
* Reload colors from resources.
**/
public void reloadColors() {
/*
int textColor = Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)
.getDefaultColor();
mDrawPaint.setColor(textColor);
*/
mDrawPaint.setColor(Color.WHITE);
}
结合
frameworks/base/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
frameworks/base/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
中的PasswordTextView进行修改
<com.android.keyguard.PasswordTextView
android:id="@+id/simPinEntry"
android:layout_width="match_parent"
android:layout_height="@dimen/keyguard_password_height"
android:gravity="center"
android:layout_alignParentStart="true"
androidprv:scaledTextSize="@integer/scaled_password_text_size"
android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
/>
屏敝“正在解锁 SIM卡”的提示
PIN码输入正确时,会弹一个几秒的文本提示“正在解锁 SIM 卡”
frameworks/base/packages/SystemUI$ grep -nr "正在解锁"
res-keyguard/values-zh-rCN/strings.xml:52: <string name="keyguard_sim_unlock_progress_dialog_message" msgid="2394023844117630429">"正在解锁 SIM 卡…"</string>
res-keyguard/values-zh-rCN/strings.xml:81: <string name="kg_sim_unlock_progress_dialog_message" msgid="4251352015304070326">"正在解锁 SIM 卡…"</string>
src/com/android/keyguard/KeyguardSimPukViewController.java:202: msg = com.android.systemui.R.string.keyguard_sim_unlock_progress_dialog_message;
src/com/android/keyguard/KeyguardSimPukViewController.java:442: mView.getResources().getString(R.string.kg_sim_unlock_progress_dialog_message));
src/com/android/keyguard/KeyguardSimPinViewController.java:279: mView.getResources().getString(R.string.kg_sim_unlock_progress_dialog_message));
src-unisoc/com/unisoc/keyguard/KeyguardSimLockViewController.java:339: mView.getContext().getString(R.string.kg_sim_unlock_progress_dialog_message));
解锁PIN码对应源码为
frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
其显示的对应框是由getSimUnlockProgressDialog返回的
private Dialog getSimUnlockProgressDialog() {
if (mSimUnlockProgressDialog == null) {
mSimUnlockProgressDialog = new ProgressDialog(mView.getContext());
mSimUnlockProgressDialog.setMessage(
mView.getResources().getString(R.string.kg_sim_unlock_progress_dialog_message));
mSimUnlockProgressDialog.setIndeterminate(true);
mSimUnlockProgressDialog.setCancelable(false);
mSimUnlockProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
return mSimUnlockProgressDialog;
}
如下图,通过getSimUnlockProgressDialog().show()来显示,如果要屏蔽掉,则直接注释或删除这行代码就行
解锁过程代码
与Android 11类似的,可参照最下方的相关文章中Android 11的流程详解
frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
verifyPasswordAndUnlock()函数是解锁时调用的, 下面代码我会在主要的代码点做注释
@Override
protected void verifyPasswordAndUnlock() {
String entry = mPasswordEntry.getText();
// SIM PIN码必须大于等于4,小于等于8,如果长度不对这里会提示错误
if (entry.length() > 8 || entry.length() < 4) {
// otherwise, display a message to the user, and don't submit.
mMessageAreaController.setMessage(
com.android.systemui.R.string.kg_invalid_sim_pin_hint);
mView.resetPasswordText(true /* animate */, true /* announce */);
getKeyguardSecurityCallback().userActivity();
return;
}
/* UNISOC: add for bug933599 @{ */
if (mKeyguardUpdateMonitor.getSimState(mSubId) != TelephonyManager.SIM_STATE_PIN_REQUIRED) {
Log.d(LOG_TAG, "keyguard sim state : " + mKeyguardUpdateMonitor.getSimState(mSubId) + ";" +
"mSubId : " + mSubId);
return;
}
/* @} */
// 这里会有一个几秒闪一下的文本提示,提示正在解锁中
getSimUnlockProgressDialog().show();
if (mCheckSimPinThread == null) {
// 调用CheckSimPin对输入的PIN进行解锁尝试
mCheckSimPinThread = new CheckSimPin(mPasswordEntry.getText(), mSubId) {
@Override
void onSimCheckResponse(final PinResult result) {
// 这里是解锁的回调
mView.post(() -> {
mRemainingAttempts = result.getAttemptsRemaining();
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.hide();
}
mView.resetPasswordText(true /* animate */,
/* announce */
result.getResult() != PinResult.PIN_RESULT_TYPE_SUCCESS);
if (result.getResult() == PinResult.PIN_RESULT_TYPE_SUCCESS) {
// 解锁成功
mShowDefaultMessage = false; // UNISOC: Modify for Bug 1737454
mKeyguardUpdateMonitor.reportSimUnlocked(mSubId);
mRemainingAttempts = -1;
} else {
mShowDefaultMessage = true; // UNISOC: Modify for Bug 1737454
if (result.getResult() == PinResult.PIN_RESULT_TYPE_INCORRECT) {
// 如果不成功就进入错误处理,更新提示
mMessageAreaController.setMessage(getPinPasswordErrorMessage(result.getAttemptsRemaining(), false));//剩余次数变更
if (result.getAttemptsRemaining() <= 2) {
// this is getting critical - show dialog
getSimRemainingAttemptsDialog(
result.getAttemptsRemaining()).show();
} else {
// show message
mMessageAreaController.setMessage(
getPinPasswordErrorMessage(
result.getAttemptsRemaining(), false));
}
} else {
// "PIN operation failed!" - no idea what this was and no way to
// find out. :/
/* SPRD : Modify for bug 921859 @{ */
if (result.getResult() != PinResult.PIN_RESULT_TYPE_ABORTED) {
if(DEBUG) Log.d(LOG_TAG, "verifyPasswordAndUnlock show kg_password_pin_failed");
mMessageAreaController.setMessage(mView.getResources().getString(
R.string.kg_password_pin_failed));
}
/* @} */
}
if (DEBUG) {
Log.d(LOG_TAG, "verifyPasswordAndUnlock "
+ " CheckSimPin.onSimCheckResponse: " + result
+ " attemptsRemaining=" + result.getAttemptsRemaining());
}
}
getKeyguardSecurityCallback().userActivity();
mCheckSimPinThread = null;
});
}
};
mCheckSimPinThread.start();
}
}
相关文章
安卓11
Android Framework SIM卡PIN码解锁代码流程
Android Framework定制sim卡插入解锁pin码的界面
作者:帅得不敢出门