Android Security PIN 相关代码

开发项目遇到一个问题,具体描述及复制步骤如下:

就是开启"Enhanced PIN privacy"(增强的PIN隐私)的时候输入秘密的时候还是会显示数字

如下图,应该是直接是"." 不应该出现PIN 密码

想要的效果如下图:

设置的步骤如下图:

其中涉及到的部分code如下:

/frameworks/base/core/java/com/android/internal/widget/LockPatternUtils.java

/frameworks/base/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java

/frameworks/base/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java

/frameworks/base/services/core/java/com/android/server/locksettings/LockSettingsStorage.java

I.LockPatternUtils.java:

java 复制代码
/**
     * @return Whether enhanced pin privacy is enabled.
     */
    public boolean isPinEnhancedPrivacyEnabled(int userId) {
        return getBoolean(LOCK_PIN_ENHANCED_PRIVACY, false, userId);
    }

    /**
     * Set whether enhanced pin privacy is enabled.
     */
    public void setPinEnhancedPrivacyEnabled(boolean enabled, int userId) {
        setBoolean(LOCK_PIN_ENHANCED_PRIVACY, enabled, userId);
    }

private boolean getBoolean(String secureSettingKey, boolean defaultValue, int userId) {
        Log.i("TD","LockPatternUtils----->getBoolean: "+secureSettingKey);
        try {
            return getLockSettings().getBoolean(secureSettingKey, defaultValue, userId);
        } catch (RemoteException re) {
            return defaultValue;
        }
    }

    private void setBoolean(String secureSettingKey, boolean enabled, int userId) {
        Log.i("TD","LockPatternUtils----->setsetBoolean: "+secureSettingKey);
        try {
            getLockSettings().setBoolean(secureSettingKey, enabled, userId);
        } catch (RemoteException re) {
            // What can we do?
            Log.e(TAG, "Couldn't write boolean " + secureSettingKey + re);
        }
    }

II.KeyguardPinBasedInputViewController.java

java 复制代码
protected void onViewAttached() {
        super.onViewAttached();

        Log.i("TD","KeyguardPinBasedInputViewController------------->onViewAttached");
        boolean showAnimations = !mLockPatternUtils
                .isPinEnhancedPrivacyEnabled(KeyguardUpdateMonitor.getCurrentUser());
        mPasswordEntry.setShowPassword(showAnimations);
        for (NumPadKey button : mView.getButtons()) {
            button.setOnTouchListener((v, event) -> {
                if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                    mFalsingCollector.avoidGesture();
                }
                return false;
            });
            button.setAnimationEnabled(showAnimations);
        }
        mPasswordEntry.setOnKeyListener(mOnKeyListener);
        mPasswordEntry.setUserActivityListener(this::onUserInput);

        View deleteButton = mView.findViewById(R.id.delete_button);
        deleteButton.setOnTouchListener(mActionButtonTouchListener);
        deleteButton.setOnClickListener(v -> {
            // check for time-based lockouts
            Log.i("TD","KeyguardPinBasedInputViewController------------->deleteButton");
            if (mPasswordEntry.isEnabled()) {
                mPasswordEntry.deleteLastChar();
            }
        });
        deleteButton.setOnLongClickListener(v -> {
            // check for time-based lockouts
            if (mPasswordEntry.isEnabled()) {
                mView.resetPasswordText(true /* animate */, true /* announce */);
            }
            Log.i("TD","KeyguardPinBasedInputViewController------------->deleteButton#longPress");
            mView.doHapticKeyClick();
            return true;
        });

        View okButton = mView.findViewById(R.id.key_enter);
        if (okButton != null) {
            okButton.setOnTouchListener(mActionButtonTouchListener);
            okButton.setOnClickListener(v -> {
                Log.i("TD","KeyguardPinBasedInputViewController------------->okButton");
                if (mPasswordEntry.isEnabled()) {
                    verifyPasswordAndUnlock();
                }
            });
            okButton.setOnHoverListener(mLiftToActivateListener);
        }
    }

III.LockSettingsStorage.java
Pattern 的加密也会走到这边

java 复制代码
public void setBoolean(String key, boolean value, int userId) {
        Log.i("TD","LockSettingsStorage*******>setBoolean-=-key is: "+key + "  **value: "+value);
        setString(key, value ? "1" : "0", userId);
    }
    
    public void setString(String key, String value, int userId) {
        Preconditions.checkArgument(userId != USER_FRP, "cannot store lock settings for FRP user");

        writeKeyValue(key, value, userId);
        if (ArrayUtils.contains(SETTINGS_TO_BACKUP, key)) {
            BackupManager.dataChanged("com.android.providers.settings");
        }
    }
    
 public void writeKeyValue(String key, String value, int userId) {
        writeKeyValue(mOpenHelper.getWritableDatabase(), key, value, userId);
    }

    @VisibleForTesting
    public void writeKeyValue(SQLiteDatabase db, String key, String value, int userId) {
        Log.i("TD","LockSettingsService---->writeKeyValue");
        Log.i("TD","LockSettingsService---->COLUMN_KEY: "+key);
        Log.i("TD","LockSettingsService---->COLUMN_USERID: "+userId);
        Log.i("TD","LockSettingsService---->COLUMN_VALUE: "+value);
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_KEY, key);
        cv.put(COLUMN_USERID, userId);
        cv.put(COLUMN_VALUE, value);

        db.beginTransaction();
        try {
            db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?",
                    new String[] {key, Integer.toString(userId)});
            db.insert(TABLE, null, cv);
            db.setTransactionSuccessful();
            mCache.putKeyValue(key, value, userId);
        } finally {
            db.endTransaction();
        }
        dispatchChange(this);
    }    

IV.PasswordTextView.java

java 复制代码
private void startDotAppearAnimation(long delay) {
            cancelAnimator(dotAnimator);
            if (!mShowPassword) {
                // We perform an overshoot animation
                ValueAnimator overShootAnimator = ValueAnimator.ofFloat(currentDotSizeFactor,
                        DOT_OVERSHOOT_FACTOR);
                overShootAnimator.addUpdateListener(dotSizeUpdater);
                overShootAnimator.setInterpolator(mAppearInterpolator);
                long overShootDuration = (long) (DOT_APPEAR_DURATION_OVERSHOOT
                        * OVERSHOOT_TIME_POSITION);
                overShootAnimator.setDuration(overShootDuration);
                ValueAnimator settleBackAnimator = ValueAnimator.ofFloat(DOT_OVERSHOOT_FACTOR,
                        1.0f);
                settleBackAnimator.addUpdateListener(dotSizeUpdater);
                settleBackAnimator.setDuration(DOT_APPEAR_DURATION_OVERSHOOT - overShootDuration);
                settleBackAnimator.addListener(dotFinishListener);
                AnimatorSet animatorSet = new AnimatorSet();
                animatorSet.playSequentially(overShootAnimator, settleBackAnimator);
                animatorSet.setStartDelay(delay);
                animatorSet.start();
                dotAnimator = animatorSet;
            } else {
                ValueAnimator growAnimator = ValueAnimator.ofFloat(currentDotSizeFactor, 1.0f);
                growAnimator.addUpdateListener(dotSizeUpdater);
                growAnimator.setDuration((long) (APPEAR_DURATION * (1.0f - currentDotSizeFactor)));
                growAnimator.addListener(dotFinishListener);
                growAnimator.setStartDelay(delay);
                growAnimator.start();
                dotAnimator = growAnimator;
            }
            dotAnimationIsGrowing = true;
        }
java 复制代码
void startAppearAnimation() {
            boolean dotNeedsAnimation = !mShowPassword
                    && (dotAnimator == null || !dotAnimationIsGrowing);
            boolean textNeedsAnimation = mShowPassword
                    && (textAnimator == null || !textAnimationIsGrowing);
            boolean widthNeedsAnimation = (widthAnimator == null || !widthAnimationIsGrowing);
            if (dotNeedsAnimation) {
                startDotAppearAnimation(0);
            }
            if (textNeedsAnimation) {
                startTextAppearAnimation();
            }
            if (widthNeedsAnimation) {
                startWidthAppearAnimation();
            }
            if (mShowPassword) {
                postDotSwap(TEXT_VISIBILITY_DURATION);
            }
        }

出现问题的地方就是下面代码注释的部分,这个值为True.

java 复制代码
 public void append(char c) {
        if (ZTelephonyManagerCommon.IS_ZEBRA_WWAN
            && (mPasswordMaxSize != -1)
            && (mText.length() >= mPasswordMaxSize)) {
            return;
        }
        int visibleChars = mTextChars.size();
        CharSequence textbefore = getTransformedText();
        mText = mText + c;
        int newLength = mText.length();
        CharState charState;
        if (newLength > visibleChars) {
            charState = obtainCharState(c);
            mTextChars.add(charState);
        } else {
            charState = mTextChars.get(newLength - 1);
            charState.whichChar = c;
        }

//        if (XXX.orElse(false)) {
//            mShowPassword = Settings.System.getInt(mContext.getContentResolver(),
//                    Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
//        }
        Log.i("TD","mShowPassword--------->"+Settings.System.getInt(mContext.getContentResolver(),
                    Settings.System.TEXT_SHOW_PASSWORD, 1));
        charState.startAppearAnimation();

        // ensure that the previous element is being swapped
        if (newLength > 1) {
            CharState previousState = mTextChars.get(newLength - 2);
            if (previousState.isDotSwapPending) {
                previousState.swapToDotWhenAppearFinished();
            }
        }
        userActivity();
        sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length(), 0, 1);
    }
相关推荐
千里马学框架3 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo5 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077006 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼7 小时前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone8 小时前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen8 小时前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone8 小时前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui