0

In my device i already set a password of device, now i install my app which is managed by device policy manager. now when i call this method

 int currentPolicy = devicePolicyManager.getPasswordQuality(demoDeviceAdmin);
    if(currentPolicy==262144)passwordType="Alphabetic";
    else if(currentPolicy==327680)passwordType="Alphanumeric";
    else if(currentPolicy==131072)passwordType="Numeric";
    //if(currentPolicy==196608)passwordType="PASSWORD_QUALITY_NUMERIC_COMPLEX";
    else if(currentPolicy==393216)passwordType="Complex";
    else if(currentPolicy==196608)passwordType="Pattern";
    else if(currentPolicy==0)passwordType="None"; 

it gives me password type none. Now if i set password through device policy manager in my application like this

  Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);

Then now if again get password quality it gives me correct value. in First time i think device policy manager don't have or store old password type.

So my question is how to get password quality before setting password from my application through device policy manager.

Thank You

shyam002
  • 237
  • 1
  • 5
  • 19
  • Nice. Only comment I would make is rather that switching on literal values like 0x40000 (262144) it's nicer to use DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC etc. – AlgebraWinter Jul 08 '16 at 13:47

2 Answers2

0

getPasswordQuality doesn't report the quality on the current password, it only reports the policy setting of lowest allowed password quality.

Basically getPasswordQuality returns the value set using the setPasswordQuality of the admin or the aggregate value if several admins are active.

The admin can check if the current password is good enough by calling DevicePolicyManager.isActivePasswordSufficient().

Keyguard reports back the current password status to DevicePolicyManager using the hidden method setActivePasswordState.

To my knowledge, this info is not available to a third party admin app.

If an incorrect password is entered, keyguard calls DevicePolicyManager.reportFailedPasswordAttempt which initiates a factory reset if too many failed attempts have been made.

Hope this helps.

/Marek Pola (Employee of Sony Mobile)

Marek Pola
  • 200
  • 1
  • 10
  • so then my question is how can i get password type(numeric,alphanumeric etc.) of my device – shyam002 Jan 16 '16 at 12:16
  • As written above, unless you root the device, a third party application cannot to my knowledge get the status of the current password. That could be a security problem. A third party application can only get the policy password settings, e.g. int getPasswordMinimumNumeric etc. /Marek (Sony Mobile employee). – Marek Pola Jan 17 '16 at 21:12
  • how can it be security issue, i told you that i am getting password type when i set password through my app, but before that how can i get password type. – shyam002 Jan 18 '16 at 08:31
0

For devices before Android 6 (exclusive), you can get the unlocking method type by calling a hidden function getActivePasswordQuality() in class LockPatternUtils (you can call the function via Java reflection). But for Android 6 and above, I have not figured out how to get the unlocking method type.

 /**
 * Determine authentication method type (DAS, PIN, Password or Biometric)
 */
private String getAuthenticationMethodType(){
    String LOCK_PATTERN_UTILS="com.android.internal.widget.LockPatternUtils";
    String ACTIVE_PASSWORD_QUALITY="getActivePasswordQuality";

    int lockProtectionLevel=0;
    try{
        Class <?> lockPatternUtilsClass=Class.forName(LOCK_PATTERN_UTILS);
        Object lockPatternUtils=lockPatternUtilsClass.getConstructor(Context.class).newInstance(this);

        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
            // Have not figured out how to get the unlocking method type for Android 6 and above devices. The same method will not work on Android 6. See detailed explanation below.
        }else {
            Method method = lockPatternUtilsClass.getMethod(ACTIVE_PASSWORD_QUALITY);
            lockProtectionLevel=Integer.valueOf(String.valueOf(method.invoke(lockPatternUtils,null)));
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    switch (lockProtectionLevel){
        case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
        case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
            return "PIN";
        case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
        case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
        case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
            return "Password";
        case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
            return "DAS";
        case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
            return "Biometric";
        default:return "None";
    }
}

For Android 6, after all my tests so far, I found that if we still want to get the unlocking method with function getActivePasswordQuality(int userId), the app must have permission android.permission.ACCESS_KEYGUARD_SECURE_STORAGE in order to read lockscreen.password_type, and get the unlocking method. However, the permission ACCESS_KEYGUARD_SECURE_STORAGE is a signature permission, which means we need to sign the app with the same key that the manufacturers use to sign the system (or to say the permission), so as to grant the signature permission to the app successfully.

Hope this helps.