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:

/**
     * @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

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 的加密也会走到这边

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

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;
        }
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.

 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);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/275798.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Springboot实现登录注册

功能:1、实现用户的登录 2、实现用户的注册以及重名的判断 LoginControl: package com.example.demo.controls;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; imp…

Android下载gradle失败解决方法

1、在gradle-wrapper.properties文件中查看自己需要下载gradle什么版本的包和zip路径(wrapper/dists)。 2、在setting中查看Gradle的保存路径,如下图:C:/Users/Administrator/.gradle,加上第一步的zip路径得到下载grad…

java itext5 生成PDF并填充数据导出

java itext5 生成PDF并填充数据导出 依赖**文本勾选框****页眉**&#xff0c;**页脚****图片**实际图 主要功能有文本勾选框&#xff0c;页眉&#xff0c;页脚&#xff0c;图片等功能。肯定没有专业软件画的好看&#xff0c;只是一点儿方法。仅供参考。 依赖 <!--pdf-->&…

数据结构学习 Leetcode322 零钱兑换

关键词&#xff1a;动态规划 完全背包 记忆化搜索 一个套路&#xff1a; 01背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要逆序遍历完全背包&#xff1a;空间优化之后dp【target1】&#xff0c;遍历的时候要正序遍历 题目&#xff1a; 方法一&#xff…

CodeWhisperer——轻松使用一个超级强大的工具

CodeWhisperer 简介 CodeWhisperer是亚⻢逊云科技出品的一款基于机器学习的通用代码生成器&#xff0c;可实时提供代码建议。 CodeWhisperer有以下几个主要用途&#xff1a; 解决编程问题&#xff0c;提供代码建议&#xff0c;学习编程知识等等&#xff0c;并且CodeWhisper…

LLM(八)| Gemini语言能力深度观察

论文地址&#xff1a;https://simg.baai.ac.cn/paperfile/fc2138ce-cadb-4a36-b9f7-c4000dea3369.pdf 谷歌最近发布的Gemini系列模型是第一个在各种任务与OpenAI GPT系列相媲美的模型。在本文中&#xff0c;作者对Gemini的语言能力做了深入的探索&#xff0c;做出了两方面的贡献…

微信小程序开发系列-06事件

什么是事件 事件是视图层到逻辑层的通讯方式。事件可以将用户的行为反馈到逻辑层进行处理。事件可以绑定在组件上&#xff0c;当达到触发条件时&#xff0c;就会执行逻辑层中对应的事件处理函数。事件对象可以携带额外信息&#xff0c;如 id, dataset, touches。 事件分类 事…

C实现数组奇数在前偶数在后排序

一、运行结果&#xff1b; 二、源码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现调整函数move_odd_even函数&#xff1b; void move_odd_even(int arr[], int sz) {//初始化变量值&#xff1b;int left 0;int right sz - 1;//循环判断和…

Arduino开发实例-ADS1232高精度24位ADC数据采样

ADS1232高精度24位ADC数据采样 文章目录 ADS1232高精度24位ADC数据采样1、ADS1232介绍2、硬件准备及接线3、驱动实现1、ADS1232介绍 几乎所有的微控制器都带有 ADC 引脚,但它们缺乏高精度。 在很多项目中,需要对模拟量进行高精度的测量,或者被测信号的电压电平不在单片机的…

2022年全国职业院校技能大赛高职组云计算正式赛卷第三场-公有云

2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 目录 2022 年全国职业院校技能大赛高职组云计算赛项试卷 【赛程名称】云计算赛项第三场-公有云 【任务 1】公有云服务搭建[10 分] 【任务 2】公有云服务运维[10 分] 【任务 3】公有云运维…

【我与Java的成长记】之this引用和构造方法的使用详解

系列文章目录 能看懂文字就能明白系列 C语言笔记传送门 &#x1f31f; 个人主页&#xff1a;古德猫宁- &#x1f308; 信念如阳光&#xff0c;照亮前行的每一步 文章目录 系列文章目录&#x1f308; *信念如阳光&#xff0c;照亮前行的每一步* 前言一、this的使用this引用的特…

机器学习之人工神经网络(Artificial Neural Networks,ANN)

人工神经网络(Artificial Neural Networks,ANN)是机器学习中的一种模型,灵感来源于人脑的神经网络结构。它由神经元(或称为节点)构成的层级结构组成,每个神经元接收输入并生成输出,这些输入和输出通过权重进行连接。 人工神经网络(ANN)是一种模仿生物神经系统构建的…

动态规划08--一和零

题目描述 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的大小&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 思路分析 做到这道题的时候没什么思路&a…

LSTM Siamese neural network

本文中的代码在Github仓库或Gitee仓库中可找到。 Hi, 你好。我是茶桁。 大家是否还记得&#xff0c;在「核心基础」课程中&#xff0c;我们讲过CNN以及LSTM。 卷积神经网络&#xff08;CNN&#xff09;已经在计算机视觉处理中得到广泛应用&#xff0c;不过&#xff0c;2017年…

数字化工业中的低功耗蓝牙模块:实现智能制造的关键

在数字化工业的时代&#xff0c;智能制造成为推动产业升级的关键因素之一。低功耗蓝牙模块作为数字化工业的技术支持&#xff0c;为设备之间的高效通信和数据交换提供了理想的解决方案。本文将深入探讨低功耗蓝牙模块在数字化工业中的关键作用&#xff0c;以及其如何实现智能制…

德鲁伊(Druid)链接PGsql前端请求或者后端自动任务频繁出现IOException

尝试在druid配置文件中增加&#xff1a; socket-timeout: 60000 druid一些版本默认会给链接数据库socket默认10s&#xff0c;超出10s之后socket断开&#xff0c;对于GP数据库报的个IO异常。 &#xff08;对于同样的场景mysql超出10s后提示的是socketTimeOut&#xff0c;所以相…

别再写一堆的 for 循环了!Java 8 中的 Stream 轻松遍历树形结构,是真的牛逼!

可能平常会遇到一些需求&#xff0c;比如构建菜单&#xff0c;构建树形结构&#xff0c;数据库一般就使用父id来表示&#xff0c;为了降低数据库的查询压力&#xff0c;我们可以使用Java8中的Stream流一次性把数据查出来&#xff0c;然后通过流式处理。 我们一起来看看&#x…

三维可视化智慧工地源码,数字孪生可视化大屏,微服务架构+Java+Spring Cloud +UniApp +MySql

源码技术说明 微服务架构JavaSpring Cloud UniApp MySql&#xff1b;支持多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三维可视化管理&#xff0c;与一线生产过程相融合&#…

模糊-神经网络控制 原理与工程应用(绪论)

模糊—神经网络控制原理与工程应用 绪论 模糊和确定系统 在客观世界中&#xff0c;系统可分为确定性系统和模糊性系统&#xff0c;前者可用精确数学模型加以描述&#xff0c;而后者则不能。 输入输出类型 &#xff08;&#xff42;&#xff09;的模糊性输出可通过反模糊化转换…

每周一算法:区间覆盖

问题描述 给定 N N N个闭区间 [ a i , b i ] [a_i,b_i] [ai​,bi​]&#xff0c;以及一个线段区间 [ s , t ] [s,t] [s,t]&#xff0c;请你选择尽量少的区间&#xff0c;将指定线段区间完全覆盖。 输出最少区间数&#xff0c;如果无法完全覆盖则输出 − 1 -1 −1。 输入格式…