Android12 Framework Sim卡pin与puk码解锁

插入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码的界面
作者:帅得不敢出门

<think>我收到了用户的查询:“我想了解PUK的定义或用途请问什么是PUKIT领域”。这显然是关于IT领域的知识,特别是移动通信安全方面的术语。用户直接提问了PUK是什么以及它的用途,我需要基于站内引用来构建一个准确、清晰的回答。首先,我快速回顾了提供的引用。引用[1]中提到,PUK是PersonalUnblockingKey的缩写,用于在忘记PIN解锁SIM;引用[2]进一步解释了PUC(PersonalUnlockCode)的用途,强调它是在多次输错PIN导致SIM被锁定后解锁的手段。这两个引用完全对应了用户的查询,核心内容一致:PUK是一种安全解锁工具,用户可以通过它来重置PIN以恢复SIM功能。此外,引用[5]提到SIM初始设置中包含紧急号语言,这也间接支持了SIM安全机制的上下文。用户明确说“IT领域”,所以我需要专注技术定义,避免延伸不相关内容。回答将围绕三个点展开:定义、用途和工作流程。定义部分直接引用[1]和[2],说明PUK是个人解锁;用途部分用场景描述解释它如何解除锁定;工作流程部分简化为“输PUK、设新PIN”的步骤。整个过程要自然,末尾自动生成相关问题来扩展学习路径。最后,准备相关问题:一个针对定义延伸、一个针对应用场景,覆盖“忘记PUK怎么办”的常见问题。确保所有内容基于引用,不添加猜测。回答用口语化中文保持友好。</think> 基于提供的引用信息,PUK的定义和用途可总结如下: **PUK的定义** PUK(Personal Unblocking Key,个人解锁)是SIM中的一种安全机制。它由移动运营商在SIM生产时分配,通常为8位数字代(引用[1]),SIM唯一绑定。在部分文献中也被称为PUC(Personal Unlock Code),本质相同(引用[2])。 **核心用途** 当用户**连续输错SIMPIN3次及以上**时触发锁定(引用[2]),此时: 1. **解除SIM锁定**:需输入正确的PUK才能解锁被锁定的SIM 2. **重置PIN**:解锁后系统会强制用户设置新的PIN(引用[1][2]) **工作流程示意图** ``` 连续输错PIN3次 → SIM锁定 → 输入PUK验证 → 设置PIN → 恢复使用 ``` **安全意义** 这种双重验证机制(PIN+PUK)实现了: - 防止非授权用户访问SIM数据(引用[1]) - 在遗忘PIN时提供合法恢复途径(引用[2]) - 避免因误操作导致SIM永久锁死 > ⚠️ **注意事项** > PUK通常印刷在SIM套或可通过运营商客服获取。若连续输错PUK10次,可能导致SIM永久报废需补办(引用[1][2]延伸知识)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅得不敢出门

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值