Fix 2677197: Adding minimum complex character support.
Change-Id: I520bc5f9aa924bf9b5585b2235a91cc96cb99c25
This commit is contained in:
151
api/current.xml
151
api/current.xml
@@ -31769,6 +31769,71 @@
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getPasswordMinimumLetters"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getPasswordMinimumLowerCase"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getPasswordMinimumNumeric"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getPasswordMinimumSymbols"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getPasswordMinimumUpperCase"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="getPasswordQuality"
|
||||
return="int"
|
||||
abstract="false"
|
||||
@@ -31905,6 +31970,81 @@
|
||||
<parameter name="length" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setPasswordMinimumLetters"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
<parameter name="length" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setPasswordMinimumLowerCase"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
<parameter name="length" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setPasswordMinimumNumeric"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
<parameter name="length" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setPasswordMinimumSymbols"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
<parameter name="length" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setPasswordMinimumUpperCase"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="admin" type="android.content.ComponentName">
|
||||
</parameter>
|
||||
<parameter name="length" type="int">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setPasswordQuality"
|
||||
return="void"
|
||||
abstract="false"
|
||||
@@ -31999,6 +32139,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="PASSWORD_QUALITY_COMPLEX"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="393216"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="PASSWORD_QUALITY_NUMERIC"
|
||||
type="int"
|
||||
transient="false"
|
||||
|
||||
@@ -204,6 +204,14 @@ public class DevicePolicyManager {
|
||||
*/
|
||||
public static final int PASSWORD_QUALITY_ALPHANUMERIC = 0x50000;
|
||||
|
||||
/**
|
||||
* Constant for {@link #setPasswordQuality}: the user must have entered a
|
||||
* password containing numeric <em>and</em> alphabetic characters,
|
||||
* <em>and</em> special symbols. Note that quality constants are ordered so
|
||||
* that higher values are more restrictive.
|
||||
*/
|
||||
public static final int PASSWORD_QUALITY_COMPLEX = 0x60000;
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the
|
||||
* password restrictions it is imposing. After setting this, the user
|
||||
@@ -226,7 +234,7 @@ public class DevicePolicyManager {
|
||||
* @param quality The new desired quality. One of
|
||||
* {@link #PASSWORD_QUALITY_UNSPECIFIED}, {@link #PASSWORD_QUALITY_SOMETHING},
|
||||
* {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC},
|
||||
* or {@link #PASSWORD_QUALITY_ALPHANUMERIC}.
|
||||
* {@link #PASSWORD_QUALITY_ALPHANUMERIC} or {@link #PASSWORD_QUALITY_COMPLEX}.
|
||||
*/
|
||||
public void setPasswordQuality(ComponentName admin, int quality) {
|
||||
if (mService != null) {
|
||||
@@ -264,8 +272,8 @@ public class DevicePolicyManager {
|
||||
* take place immediately. To prompt the user for a new password, use
|
||||
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
|
||||
* constraint is only imposed if the administrator has also requested either
|
||||
* {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC},
|
||||
* or {@link #PASSWORD_QUALITY_ALPHANUMERIC}
|
||||
* {@link #PASSWORD_QUALITY_NUMERIC}, {@link #PASSWORD_QUALITY_ALPHABETIC}
|
||||
* {@link #PASSWORD_QUALITY_ALPHANUMERIC}, or {@link #PASSWORD_QUALITY_COMPLEX}
|
||||
* with {@link #setPasswordQuality}.
|
||||
*
|
||||
* <p>The calling device admin must have requested
|
||||
@@ -303,6 +311,255 @@ public class DevicePolicyManager {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the
|
||||
* minimum number of upper case letters required in the password. After
|
||||
* setting this, the user will not be able to enter a new password that is
|
||||
* not at least as restrictive as what has been set. Note that the current
|
||||
* password will remain until the user has set a new one, so the change does
|
||||
* not take place immediately. To prompt the user for a new password, use
|
||||
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
|
||||
* constraint is only imposed if the administrator has also requested
|
||||
* {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
|
||||
* <p>
|
||||
* The calling device admin must have requested
|
||||
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
|
||||
* this method; if it has not, a security exception will be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated
|
||||
* with.
|
||||
* @param length The new desired minimum number of upper case letters
|
||||
* required in the password. A value of 0 means there is no
|
||||
* restriction.
|
||||
*/
|
||||
public void setPasswordMinimumUpperCase(ComponentName admin, int length) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setPasswordMinimumUpperCase(admin, length);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current number of upper case letters required in the
|
||||
* password for all admins or a particular one.
|
||||
*
|
||||
* @param admin The name of the admin component to check, or null to
|
||||
* aggregate all admins.
|
||||
* @return The minimum number of upper case letters required in the
|
||||
* password.
|
||||
*/
|
||||
public int getPasswordMinimumUpperCase(ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPasswordMinimumUpperCase(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the
|
||||
* minimum number of lower case letters required in the password. After
|
||||
* setting this, the user will not be able to enter a new password that is
|
||||
* not at least as restrictive as what has been set. Note that the current
|
||||
* password will remain until the user has set a new one, so the change does
|
||||
* not take place immediately. To prompt the user for a new password, use
|
||||
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
|
||||
* constraint is only imposed if the administrator has also requested
|
||||
* {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
|
||||
* <p>
|
||||
* The calling device admin must have requested
|
||||
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
|
||||
* this method; if it has not, a security exception will be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated
|
||||
* with.
|
||||
* @param length The new desired minimum number of lower case letters
|
||||
* required in the password. A value of 0 means there is no
|
||||
* restriction.
|
||||
*/
|
||||
public void setPasswordMinimumLowerCase(ComponentName admin, int length) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setPasswordMinimumLowerCase(admin, length);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current number of lower case letters required in the
|
||||
* password for all admins or a particular one.
|
||||
*
|
||||
* @param admin The name of the admin component to check, or null to
|
||||
* aggregate all admins.
|
||||
* @return The minimum number of lower case letters required in the
|
||||
* password.
|
||||
*/
|
||||
public int getPasswordMinimumLowerCase(ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPasswordMinimumLowerCase(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the
|
||||
* minimum number of letters required in the password. After setting this,
|
||||
* the user will not be able to enter a new password that is not at least as
|
||||
* restrictive as what has been set. Note that the current password will
|
||||
* remain until the user has set a new one, so the change does not take
|
||||
* place immediately. To prompt the user for a new password, use
|
||||
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
|
||||
* constraint is only imposed if the administrator has also requested
|
||||
* {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
|
||||
* <p>
|
||||
* The calling device admin must have requested
|
||||
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
|
||||
* this method; if it has not, a security exception will be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated
|
||||
* with.
|
||||
* @param length The new desired minimum number of letters required in the
|
||||
* password. A value of 0 means there is no restriction.
|
||||
*/
|
||||
public void setPasswordMinimumLetters(ComponentName admin, int length) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setPasswordMinimumLetters(admin, length);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current number of letters required in the password for all
|
||||
* admins or a particular one.
|
||||
*
|
||||
* @param admin The name of the admin component to check, or null to
|
||||
* aggregate all admins.
|
||||
* @return The minimum number of letters required in the password.
|
||||
*/
|
||||
public int getPasswordMinimumLetters(ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPasswordMinimumLetters(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the
|
||||
* minimum number of numerical digits required in the password. After
|
||||
* setting this, the user will not be able to enter a new password that is
|
||||
* not at least as restrictive as what has been set. Note that the current
|
||||
* password will remain until the user has set a new one, so the change does
|
||||
* not take place immediately. To prompt the user for a new password, use
|
||||
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
|
||||
* constraint is only imposed if the administrator has also requested
|
||||
* {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
|
||||
* <p>
|
||||
* The calling device admin must have requested
|
||||
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
|
||||
* this method; if it has not, a security exception will be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated
|
||||
* with.
|
||||
* @param length The new desired minimum number of numerical digits required
|
||||
* in the password. A value of 0 means there is no restriction.
|
||||
*/
|
||||
public void setPasswordMinimumNumeric(ComponentName admin, int length) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setPasswordMinimumNumeric(admin, length);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current number of numerical digits required in the password
|
||||
* for all admins or a particular one.
|
||||
*
|
||||
* @param admin The name of the admin component to check, or null to
|
||||
* aggregate all admins.
|
||||
* @return The minimum number of numerical digits required in the password.
|
||||
*/
|
||||
public int getPasswordMinimumNumeric(ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPasswordMinimumNumeric(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the
|
||||
* minimum number of symbols required in the password. After setting this,
|
||||
* the user will not be able to enter a new password that is not at least as
|
||||
* restrictive as what has been set. Note that the current password will
|
||||
* remain until the user has set a new one, so the change does not take
|
||||
* place immediately. To prompt the user for a new password, use
|
||||
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value. This
|
||||
* constraint is only imposed if the administrator has also requested
|
||||
* {@link #PASSWORD_QUALITY_COMPLEX} with {@link #setPasswordQuality}.
|
||||
* <p>
|
||||
* The calling device admin must have requested
|
||||
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
|
||||
* this method; if it has not, a security exception will be thrown.
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated
|
||||
* with.
|
||||
* @param length The new desired minimum number of symbols required in the
|
||||
* password. A value of 0 means there is no restriction.
|
||||
*/
|
||||
public void setPasswordMinimumSymbols(ComponentName admin, int length) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setPasswordMinimumSymbols(admin, length);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current number of symbols required in the password for all
|
||||
* admins or a particular one.
|
||||
*
|
||||
* @param admin The name of the admin component to check, or null to
|
||||
* aggregate all admins.
|
||||
* @return The minimum number of symbols required in the password.
|
||||
*/
|
||||
public int getPasswordMinimumSymbols(ComponentName admin) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
return mService.getPasswordMinimumSymbols(admin);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by an application that is administering the device to set the length
|
||||
* of the password history. After setting this, the user will not be able to
|
||||
@@ -627,10 +884,12 @@ public class DevicePolicyManager {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setActivePasswordState(int quality, int length) {
|
||||
public void setActivePasswordState(int quality, int length, int letters, int uppercase,
|
||||
int lowercase, int numbers, int symbols) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.setActivePasswordState(quality, length);
|
||||
mService.setActivePasswordState(quality, length, letters, uppercase, lowercase,
|
||||
numbers, symbols);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed talking with device policy service", e);
|
||||
}
|
||||
|
||||
@@ -27,9 +27,24 @@ import android.os.RemoteCallback;
|
||||
interface IDevicePolicyManager {
|
||||
void setPasswordQuality(in ComponentName who, int quality);
|
||||
int getPasswordQuality(in ComponentName who);
|
||||
|
||||
|
||||
void setPasswordMinimumLength(in ComponentName who, int length);
|
||||
int getPasswordMinimumLength(in ComponentName who);
|
||||
|
||||
void setPasswordMinimumUpperCase(in ComponentName who, int length);
|
||||
int getPasswordMinimumUpperCase(in ComponentName who);
|
||||
|
||||
void setPasswordMinimumLowerCase(in ComponentName who, int length);
|
||||
int getPasswordMinimumLowerCase(in ComponentName who);
|
||||
|
||||
void setPasswordMinimumLetters(in ComponentName who, int length);
|
||||
int getPasswordMinimumLetters(in ComponentName who);
|
||||
|
||||
void setPasswordMinimumNumeric(in ComponentName who, int length);
|
||||
int getPasswordMinimumNumeric(in ComponentName who);
|
||||
|
||||
void setPasswordMinimumSymbols(in ComponentName who, int length);
|
||||
int getPasswordMinimumSymbols(in ComponentName who);
|
||||
|
||||
void setPasswordHistoryLength(in ComponentName who, int length);
|
||||
int getPasswordHistoryLength(in ComponentName who);
|
||||
@@ -56,7 +71,7 @@ interface IDevicePolicyManager {
|
||||
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result);
|
||||
void removeActiveAdmin(in ComponentName policyReceiver);
|
||||
|
||||
void setActivePasswordState(int quality, int length);
|
||||
void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase, int numbers, int symbols);
|
||||
void reportFailedPasswordAttempt();
|
||||
void reportSuccessfulPasswordAttempt();
|
||||
}
|
||||
|
||||
@@ -144,6 +144,26 @@ public class LockPatternUtils {
|
||||
return getDevicePolicyManager().getPasswordHistoryLength(null);
|
||||
}
|
||||
|
||||
public int getRequestedPasswordMinimumLetters() {
|
||||
return getDevicePolicyManager().getPasswordMinimumLetters(null);
|
||||
}
|
||||
|
||||
public int getRequestedPasswordMinimumUpperCase() {
|
||||
return getDevicePolicyManager().getPasswordMinimumUpperCase(null);
|
||||
}
|
||||
|
||||
public int getRequestedPasswordMinimumLowerCase() {
|
||||
return getDevicePolicyManager().getPasswordMinimumLowerCase(null);
|
||||
}
|
||||
|
||||
public int getRequestedPasswordMinimumNumeric() {
|
||||
return getDevicePolicyManager().getPasswordMinimumNumeric(null);
|
||||
}
|
||||
|
||||
public int getRequestedPasswordMinimumSymbols() {
|
||||
return getDevicePolicyManager().getPasswordMinimumSymbols(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual password mode, as set by keyguard after updating the password.
|
||||
*
|
||||
@@ -308,6 +328,11 @@ public class LockPatternUtils {
|
||||
activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
|
||||
}
|
||||
break;
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
|
||||
if (isLockPasswordEnabled()) {
|
||||
activePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return activePasswordQuality;
|
||||
}
|
||||
@@ -316,8 +341,6 @@ public class LockPatternUtils {
|
||||
* Clear any lock pattern or password.
|
||||
*/
|
||||
public void clearLock() {
|
||||
getDevicePolicyManager().setActivePasswordState(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
|
||||
saveLockPassword(null, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
|
||||
setLockPatternEnabled(false);
|
||||
saveLockPattern(null);
|
||||
@@ -330,7 +353,7 @@ public class LockPatternUtils {
|
||||
*/
|
||||
public void saveLockPattern(List<LockPatternView.Cell> pattern) {
|
||||
// Compute the hash
|
||||
final byte[] hash = LockPatternUtils.patternToHash(pattern);
|
||||
final byte[] hash = LockPatternUtils.patternToHash(pattern);
|
||||
try {
|
||||
// Write the hash to file
|
||||
RandomAccessFile raf = new RandomAccessFile(sLockPatternFilename, "rw");
|
||||
@@ -345,14 +368,15 @@ public class LockPatternUtils {
|
||||
if (pattern != null) {
|
||||
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
|
||||
setLong(PASSWORD_TYPE_KEY, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);
|
||||
dpm.setActivePasswordState(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size());
|
||||
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern
|
||||
.size(), 0, 0, 0, 0, 0);
|
||||
} else {
|
||||
dpm.setActivePasswordState(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
|
||||
dpm.setActivePasswordState(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0,
|
||||
0, 0, 0, 0);
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// Cant do much, unless we want to fail over to using the settings provider
|
||||
// Cant do much, unless we want to fail over to using the settings
|
||||
// provider
|
||||
Log.e(TAG, "Unable to save lock pattern to " + sLockPatternFilename);
|
||||
} catch (IOException ioe) {
|
||||
// Cant do much
|
||||
@@ -410,13 +434,33 @@ public class LockPatternUtils {
|
||||
DevicePolicyManager dpm = getDevicePolicyManager();
|
||||
if (password != null) {
|
||||
int computedQuality = computePasswordQuality(password);
|
||||
setLong(PASSWORD_TYPE_KEY, computedQuality);
|
||||
setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality));
|
||||
if (computedQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
|
||||
dpm.setActivePasswordState(computedQuality, password.length());
|
||||
int letters = 0;
|
||||
int uppercase = 0;
|
||||
int lowercase = 0;
|
||||
int numbers = 0;
|
||||
int symbols = 0;
|
||||
for (int i = 0; i < password.length(); i++) {
|
||||
char c = password.charAt(i);
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
letters++;
|
||||
uppercase++;
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
letters++;
|
||||
lowercase++;
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
numbers++;
|
||||
} else {
|
||||
symbols++;
|
||||
}
|
||||
}
|
||||
dpm.setActivePasswordState(Math.max(quality, computedQuality), password
|
||||
.length(), letters, uppercase, lowercase, numbers, symbols);
|
||||
} else {
|
||||
// The password is not anything.
|
||||
dpm.setActivePasswordState(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
// Add the password to the password history. We assume all
|
||||
// password
|
||||
@@ -439,7 +483,7 @@ public class LockPatternUtils {
|
||||
setString(PASSWORD_HISTORY_KEY, passwordHistory);
|
||||
} else {
|
||||
dpm.setActivePasswordState(
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0);
|
||||
DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
// Cant do much, unless we want to fail over to using the settings provider
|
||||
@@ -579,7 +623,8 @@ public class LockPatternUtils {
|
||||
return savedPasswordExists() &&
|
||||
(mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -716,7 +761,8 @@ public class LockPatternUtils {
|
||||
final boolean isPattern = mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
final boolean isPassword = mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
|
||||
|| mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
|
||||
final boolean secure = isPattern && isLockPatternEnabled() && savedPatternExists()
|
||||
|| isPassword && savedPasswordExists();
|
||||
return secure;
|
||||
|
||||
@@ -667,6 +667,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
|
||||
currentMode = UnlockMode.Password;
|
||||
break;
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
|
||||
|
||||
@@ -88,7 +88,8 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
|
||||
|
||||
final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality();
|
||||
final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality;
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
|
||||
|
||||
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
|
||||
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
|
||||
@@ -200,7 +201,8 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
|
||||
mPasswordEntry.setEnabled(true);
|
||||
final int quality = mLockPatternUtils.getKeyguardStoredPasswordQuality();
|
||||
final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality;
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|
||||
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
|
||||
if(isAlpha) {
|
||||
mTitle.setText(R.string.keyguard_password_enter_password_code);
|
||||
} else {
|
||||
|
||||
@@ -75,6 +75,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
|
||||
int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
int mActivePasswordLength = 0;
|
||||
int mActivePasswordUpperCase = 0;
|
||||
int mActivePasswordLowerCase = 0;
|
||||
int mActivePasswordLetters = 0;
|
||||
int mActivePasswordNumeric = 0;
|
||||
int mActivePasswordSymbols = 0;
|
||||
int mFailedPasswordAttempts = 0;
|
||||
|
||||
int mPasswordOwner = -1;
|
||||
@@ -90,6 +95,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
int minimumPasswordLength = 0;
|
||||
int passwordHistoryLength = 0;
|
||||
int minimumPasswordUpperCase = 0;
|
||||
int minimumPasswordLowerCase = 0;
|
||||
int minimumPasswordLetters = 1;
|
||||
int minimumPasswordNumeric = 1;
|
||||
int minimumPasswordSymbols = 1;
|
||||
long maximumTimeToUnlock = 0;
|
||||
int maximumFailedPasswordsForWipe = 0;
|
||||
|
||||
@@ -118,6 +128,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
out.attribute(null, "value", Integer.toString(passwordHistoryLength));
|
||||
out.endTag(null, "password-history-length");
|
||||
}
|
||||
if (minimumPasswordUpperCase > 0) {
|
||||
out.startTag(null, "min-password-uppercase");
|
||||
out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase));
|
||||
out.endTag(null, "min-password-uppercase");
|
||||
}
|
||||
if (minimumPasswordLowerCase > 0) {
|
||||
out.startTag(null, "min-password-lowercase");
|
||||
out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase));
|
||||
out.endTag(null, "min-password-lowercase");
|
||||
}
|
||||
if (minimumPasswordLetters > 0) {
|
||||
out.startTag(null, "min-password-letters");
|
||||
out.attribute(null, "value", Integer.toString(minimumPasswordLetters));
|
||||
out.endTag(null, "min-password-letters");
|
||||
}
|
||||
if (minimumPasswordNumeric > 0) {
|
||||
out.startTag(null, "min-password-numeric");
|
||||
out.attribute(null, "value", Integer.toString(minimumPasswordNumeric));
|
||||
out.endTag(null, "min-password-numeric");
|
||||
}
|
||||
if (minimumPasswordSymbols > 0) {
|
||||
out.startTag(null, "min-password-symbols");
|
||||
out.attribute(null, "value", Integer.toString(minimumPasswordSymbols));
|
||||
out.endTag(null, "min-password-symbols");
|
||||
}
|
||||
}
|
||||
if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
|
||||
out.startTag(null, "max-time-to-unlock");
|
||||
@@ -152,6 +187,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
} else if ("password-history-length".equals(tag)) {
|
||||
passwordHistoryLength = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("min-password-uppercase".equals(tag)) {
|
||||
minimumPasswordUpperCase = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("min-password-lowercase".equals(tag)) {
|
||||
minimumPasswordLowerCase = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("min-password-letters".equals(tag)) {
|
||||
minimumPasswordLetters = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("min-password-numeric".equals(tag)) {
|
||||
minimumPasswordNumeric = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("min-password-symbols".equals(tag)) {
|
||||
minimumPasswordSymbols = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
} else if ("max-time-to-unlock".equals(tag)) {
|
||||
maximumTimeToUnlock = Long.parseLong(
|
||||
parser.getAttributeValue(null, "value"));
|
||||
@@ -180,6 +230,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
pw.println(minimumPasswordLength);
|
||||
pw.print(prefix); pw.print("passwordHistoryLength=");
|
||||
pw.println(passwordHistoryLength);
|
||||
pw.print(prefix); pw.print("minimumPasswordUpperCase=");
|
||||
pw.println(minimumPasswordUpperCase);
|
||||
pw.print(prefix); pw.print("minimumPasswordLowerCase=");
|
||||
pw.println(minimumPasswordLowerCase);
|
||||
pw.print(prefix); pw.print("minimumPasswordLetters=");
|
||||
pw.println(minimumPasswordLetters);
|
||||
pw.print(prefix); pw.print("minimumPasswordNumeric=");
|
||||
pw.println(minimumPasswordNumeric);
|
||||
pw.print(prefix); pw.print("minimumPasswordSymbols=");
|
||||
pw.println(minimumPasswordSymbols);
|
||||
pw.print(prefix); pw.print("maximumTimeToUnlock=");
|
||||
pw.println(maximumTimeToUnlock);
|
||||
pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
|
||||
@@ -366,10 +426,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
out.endTag(null, "failed-password-attempts");
|
||||
}
|
||||
|
||||
if (mActivePasswordQuality != 0 || mActivePasswordLength != 0) {
|
||||
if (mActivePasswordQuality != 0 || mActivePasswordLength != 0
|
||||
|| mActivePasswordUpperCase != 0 || mActivePasswordLowerCase != 0
|
||||
|| mActivePasswordLetters != 0 || mActivePasswordNumeric != 0
|
||||
|| mActivePasswordSymbols != 0) {
|
||||
out.startTag(null, "active-password");
|
||||
out.attribute(null, "quality", Integer.toString(mActivePasswordQuality));
|
||||
out.attribute(null, "length", Integer.toString(mActivePasswordLength));
|
||||
out.attribute(null, "uppercase", Integer.toString(mActivePasswordUpperCase));
|
||||
out.attribute(null, "lowercase", Integer.toString(mActivePasswordLowerCase));
|
||||
out.attribute(null, "letters", Integer.toString(mActivePasswordLetters));
|
||||
out.attribute(null, "numeric", Integer
|
||||
.toString(mActivePasswordNumeric));
|
||||
out.attribute(null, "symbols", Integer.toString(mActivePasswordSymbols));
|
||||
out.endTag(null, "active-password");
|
||||
}
|
||||
|
||||
@@ -443,6 +512,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
parser.getAttributeValue(null, "quality"));
|
||||
mActivePasswordLength = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "length"));
|
||||
mActivePasswordUpperCase = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "uppercase"));
|
||||
mActivePasswordLowerCase = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "lowercase"));
|
||||
mActivePasswordLetters = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "letters"));
|
||||
mActivePasswordNumeric = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "numeric"));
|
||||
mActivePasswordSymbols = Integer.parseInt(
|
||||
parser.getAttributeValue(null, "symbols"));
|
||||
XmlUtils.skipCurrentTag(parser);
|
||||
} else {
|
||||
Slog.w(TAG, "Unknown tag: " + tag);
|
||||
@@ -480,6 +559,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
+ Integer.toHexString(utils.getActivePasswordQuality()));
|
||||
mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
|
||||
mActivePasswordLength = 0;
|
||||
mActivePasswordUpperCase = 0;
|
||||
mActivePasswordLowerCase = 0;
|
||||
mActivePasswordLetters = 0;
|
||||
mActivePasswordNumeric = 0;
|
||||
mActivePasswordSymbols = 0;
|
||||
}
|
||||
|
||||
validatePasswordOwnerLocked();
|
||||
@@ -502,6 +586,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid quality constant: 0x"
|
||||
@@ -712,14 +797,194 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public void setPasswordMinimumUpperCase(ComponentName who, int length) {
|
||||
synchronized (this) {
|
||||
if (who == null) {
|
||||
throw new NullPointerException("ComponentName is null");
|
||||
}
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
|
||||
if (ap.minimumPasswordUpperCase != length) {
|
||||
ap.minimumPasswordUpperCase = length;
|
||||
saveSettingsLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getPasswordMinimumUpperCase(ComponentName who) {
|
||||
synchronized (this) {
|
||||
int length = 0;
|
||||
|
||||
if (who != null) {
|
||||
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
|
||||
return admin != null ? admin.minimumPasswordUpperCase : length;
|
||||
}
|
||||
|
||||
final int N = mAdminList.size();
|
||||
for (int i=0; i<N; i++) {
|
||||
ActiveAdmin admin = mAdminList.get(i);
|
||||
if (length < admin.minimumPasswordUpperCase) {
|
||||
length = admin.minimumPasswordUpperCase;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPasswordMinimumLowerCase(ComponentName who, int length) {
|
||||
synchronized (this) {
|
||||
if (who == null) {
|
||||
throw new NullPointerException("ComponentName is null");
|
||||
}
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
|
||||
if (ap.minimumPasswordLowerCase != length) {
|
||||
ap.minimumPasswordLowerCase = length;
|
||||
saveSettingsLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getPasswordMinimumLowerCase(ComponentName who) {
|
||||
synchronized (this) {
|
||||
int length = 0;
|
||||
|
||||
if (who != null) {
|
||||
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
|
||||
return admin != null ? admin.minimumPasswordLowerCase : length;
|
||||
}
|
||||
|
||||
final int N = mAdminList.size();
|
||||
for (int i=0; i<N; i++) {
|
||||
ActiveAdmin admin = mAdminList.get(i);
|
||||
if (length < admin.minimumPasswordLowerCase) {
|
||||
length = admin.minimumPasswordLowerCase;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPasswordMinimumLetters(ComponentName who, int length) {
|
||||
synchronized (this) {
|
||||
if (who == null) {
|
||||
throw new NullPointerException("ComponentName is null");
|
||||
}
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
|
||||
if (ap.minimumPasswordLetters != length) {
|
||||
ap.minimumPasswordLetters = length;
|
||||
saveSettingsLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getPasswordMinimumLetters(ComponentName who) {
|
||||
synchronized (this) {
|
||||
int length = 0;
|
||||
|
||||
if (who != null) {
|
||||
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
|
||||
return admin != null ? admin.minimumPasswordLetters : length;
|
||||
}
|
||||
|
||||
final int N = mAdminList.size();
|
||||
for (int i=0; i<N; i++) {
|
||||
ActiveAdmin admin = mAdminList.get(i);
|
||||
if (length < admin.minimumPasswordLetters) {
|
||||
length = admin.minimumPasswordLetters;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPasswordMinimumNumeric(ComponentName who, int length) {
|
||||
synchronized (this) {
|
||||
if (who == null) {
|
||||
throw new NullPointerException("ComponentName is null");
|
||||
}
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
|
||||
if (ap.minimumPasswordNumeric != length) {
|
||||
ap.minimumPasswordNumeric = length;
|
||||
saveSettingsLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getPasswordMinimumNumeric(ComponentName who) {
|
||||
synchronized (this) {
|
||||
int length = 0;
|
||||
|
||||
if (who != null) {
|
||||
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
|
||||
return admin != null ? admin.minimumPasswordNumeric : length;
|
||||
}
|
||||
|
||||
final int N = mAdminList.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
ActiveAdmin admin = mAdminList.get(i);
|
||||
if (length < admin.minimumPasswordNumeric) {
|
||||
length = admin.minimumPasswordNumeric;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPasswordMinimumSymbols(ComponentName who, int length) {
|
||||
synchronized (this) {
|
||||
if (who == null) {
|
||||
throw new NullPointerException("ComponentName is null");
|
||||
}
|
||||
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
|
||||
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
|
||||
if (ap.minimumPasswordSymbols != length) {
|
||||
ap.minimumPasswordSymbols = length;
|
||||
saveSettingsLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getPasswordMinimumSymbols(ComponentName who) {
|
||||
synchronized (this) {
|
||||
int length = 0;
|
||||
|
||||
if (who != null) {
|
||||
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
|
||||
return admin != null ? admin.minimumPasswordSymbols : length;
|
||||
}
|
||||
|
||||
final int N = mAdminList.size();
|
||||
for (int i=0; i<N; i++) {
|
||||
ActiveAdmin admin = mAdminList.get(i);
|
||||
if (length < admin.minimumPasswordSymbols) {
|
||||
length = admin.minimumPasswordSymbols;
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActivePasswordSufficient() {
|
||||
synchronized (this) {
|
||||
// This API can only be called by an active device admin,
|
||||
// so try to retrieve it to check that the caller is one.
|
||||
getActiveAdminForCallerLocked(null,
|
||||
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
|
||||
return mActivePasswordQuality >= getPasswordQuality(null)
|
||||
&& mActivePasswordLength >= getPasswordMinimumLength(null);
|
||||
if (mActivePasswordQuality < getPasswordQuality(null)
|
||||
|| mActivePasswordLength < getPasswordMinimumLength(null)) {
|
||||
return false;
|
||||
}
|
||||
if(mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
|
||||
return true;
|
||||
}
|
||||
return mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null)
|
||||
&& mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null)
|
||||
&& mActivePasswordLetters >= getPasswordMinimumLetters(null)
|
||||
&& mActivePasswordNumeric >= getPasswordMinimumNumeric(null)
|
||||
&& mActivePasswordSymbols >= getPasswordMinimumSymbols(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,14 +1046,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
quality = getPasswordQuality(null);
|
||||
if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
|
||||
int realQuality = LockPatternUtils.computePasswordQuality(password);
|
||||
if (realQuality < quality) {
|
||||
if (realQuality < quality
|
||||
&& quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
|
||||
Slog.w(TAG, "resetPassword: password quality 0x"
|
||||
+ Integer.toHexString(quality)
|
||||
+ " does not meet required quality 0x"
|
||||
+ Integer.toHexString(quality));
|
||||
return false;
|
||||
}
|
||||
quality = realQuality;
|
||||
quality = Math.max(realQuality, quality);
|
||||
}
|
||||
int length = getPasswordMinimumLength(null);
|
||||
if (password.length() < length) {
|
||||
@@ -796,6 +1062,68 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
+ " does not meet required length " + length);
|
||||
return false;
|
||||
}
|
||||
if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
|
||||
int letters = 0;
|
||||
int uppercase = 0;
|
||||
int lowercase = 0;
|
||||
int numbers = 0;
|
||||
int symbols = 0;
|
||||
for (int i = 0; i < password.length(); i++) {
|
||||
char c = password.charAt(i);
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
letters++;
|
||||
uppercase++;
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
letters++;
|
||||
lowercase++;
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
numbers++;
|
||||
} else {
|
||||
symbols++;
|
||||
}
|
||||
}
|
||||
int neededLetters = getPasswordMinimumLetters(null);
|
||||
if(letters < neededLetters) {
|
||||
Slog.w(TAG, "resetPassword: number of letters " + letters
|
||||
+ " does not meet required number of letters " + neededLetters);
|
||||
return false;
|
||||
}
|
||||
int neededNumbers = getPasswordMinimumNumeric(null);
|
||||
if (numbers < neededNumbers) {
|
||||
Slog
|
||||
.w(TAG, "resetPassword: number of numerical digits " + numbers
|
||||
+ " does not meet required number of numerical digits "
|
||||
+ neededNumbers);
|
||||
return false;
|
||||
}
|
||||
int neededLowerCase = getPasswordMinimumLowerCase(null);
|
||||
if (lowercase < neededLowerCase) {
|
||||
Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase
|
||||
+ " does not meet required number of lowercase letters "
|
||||
+ neededLowerCase);
|
||||
return false;
|
||||
}
|
||||
int neededUpperCase = getPasswordMinimumUpperCase(null);
|
||||
if (uppercase < neededUpperCase) {
|
||||
Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase
|
||||
+ " does not meet required number of uppercase letters "
|
||||
+ neededUpperCase);
|
||||
return false;
|
||||
}
|
||||
int neededSymbols = getPasswordMinimumSymbols(null);
|
||||
if (symbols < neededSymbols) {
|
||||
Slog.w(TAG, "resetPassword: number of special symbols " + symbols
|
||||
+ " does not meet required number of special symbols " + neededSymbols);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
LockPatternUtils utils = new LockPatternUtils(mContext);
|
||||
if(utils.checkPasswordHistory(password)) {
|
||||
Slog.w(TAG, "resetPassword: password is the same as one of the last "
|
||||
+ getPasswordHistoryLength(null) + " passwords");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int callingUid = Binder.getCallingUid();
|
||||
@@ -946,7 +1274,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
public void setActivePasswordState(int quality, int length) {
|
||||
public void setActivePasswordState(int quality, int length, int letters, int uppercase,
|
||||
int lowercase, int numbers, int symbols) {
|
||||
mContext.enforceCallingOrSelfPermission(
|
||||
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
|
||||
|
||||
@@ -954,11 +1283,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
|
||||
synchronized (this) {
|
||||
if (mActivePasswordQuality != quality || mActivePasswordLength != length
|
||||
|| mFailedPasswordAttempts != 0) {
|
||||
|| mFailedPasswordAttempts != 0 || mActivePasswordLetters != letters
|
||||
|| mActivePasswordUpperCase != uppercase
|
||||
|| mActivePasswordLowerCase != lowercase || mActivePasswordNumeric != numbers
|
||||
|| mActivePasswordSymbols != symbols) {
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mActivePasswordQuality = quality;
|
||||
mActivePasswordLength = length;
|
||||
mActivePasswordLetters = letters;
|
||||
mActivePasswordLowerCase = lowercase;
|
||||
mActivePasswordUpperCase = uppercase;
|
||||
mActivePasswordNumeric = numbers;
|
||||
mActivePasswordSymbols = symbols;
|
||||
mFailedPasswordAttempts = 0;
|
||||
saveSettingsLocked();
|
||||
sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
|
||||
@@ -1042,6 +1379,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
|
||||
pw.print(" mActivePasswordQuality=0x");
|
||||
pw.println(Integer.toHexString(mActivePasswordQuality));
|
||||
pw.print(" mActivePasswordLength="); pw.println(mActivePasswordLength);
|
||||
pw.print(" mActivePasswordUpperCase="); pw.println(mActivePasswordUpperCase);
|
||||
pw.print(" mActivePasswordLowerCase="); pw.println(mActivePasswordLowerCase);
|
||||
pw.print(" mActivePasswordLetters="); pw.println(mActivePasswordLetters);
|
||||
pw.print(" mActivePasswordNumeric="); pw.println(mActivePasswordNumeric);
|
||||
pw.print(" mActivePasswordSymbols="); pw.println(mActivePasswordSymbols);
|
||||
pw.print(" mFailedPasswordAttempts="); pw.println(mFailedPasswordAttempts);
|
||||
pw.print(" mPasswordOwner="); pw.println(mPasswordOwner);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user