More device policy work: clarify password modes, monkeying.
Clarifies what the password modes mean, renaming them to "quality"
and updating their documentation and the implementation to follow.
Also adds a facility to find out if a monkey is running, which I
need for the api demo to avoid letting it wipe the device.
diff --git a/api/current.xml b/api/current.xml
index 3b6e031..85908c1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -17644,6 +17644,17 @@
<exception name="SecurityException" type="java.lang.SecurityException">
</exception>
</method>
+<method name="isUserAMonkey"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="killBackgroundProcesses"
return="void"
abstract="false"
@@ -20457,7 +20468,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="mode" type="int">
+<parameter name="quality" type="int">
</parameter>
</method>
<method name="getPasswordMinimumLength"
@@ -20473,7 +20484,7 @@
<parameter name="admin" type="android.content.ComponentName">
</parameter>
</method>
-<method name="getPasswordMode"
+<method name="getPasswordQuality"
return="int"
abstract="false"
native="false"
@@ -20592,7 +20603,7 @@
<parameter name="length" type="int">
</parameter>
</method>
-<method name="setPasswordMode"
+<method name="setPasswordQuality"
return="void"
abstract="false"
native="false"
@@ -20604,7 +20615,7 @@
>
<parameter name="admin" type="android.content.ComponentName">
</parameter>
-<parameter name="mode" type="int">
+<parameter name="quality" type="int">
</parameter>
</method>
<method name="wipeData"
@@ -20664,40 +20675,40 @@
visibility="public"
>
</field>
-<field name="PASSWORD_MODE_ALPHANUMERIC"
+<field name="PASSWORD_QUALITY_ALPHANUMERIC"
type="int"
transient="false"
volatile="false"
- value="3000"
+ value="196608"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="PASSWORD_MODE_NUMERIC"
+<field name="PASSWORD_QUALITY_NUMERIC"
type="int"
transient="false"
volatile="false"
- value="2000"
+ value="131072"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="PASSWORD_MODE_SOMETHING"
+<field name="PASSWORD_QUALITY_SOMETHING"
type="int"
transient="false"
volatile="false"
- value="1000"
+ value="65536"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="PASSWORD_MODE_UNSPECIFIED"
+<field name="PASSWORD_QUALITY_UNSPECIFIED"
type="int"
transient="false"
volatile="false"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 932ad53..e8ab51fd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -957,4 +957,15 @@
return null;
}
+ /**
+ * Returns "true" if the user interface is currently being messed with
+ * by a monkey.
+ */
+ public static boolean isUserAMonkey() {
+ try {
+ return ActivityManagerNative.getDefault().isUserAMonkey();
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 09b88ee..2e39c10 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1178,6 +1178,14 @@
int enterAnim = data.readInt();
int exitAnim = data.readInt();
overridePendingTransition(token, packageName, enterAnim, exitAnim);
+ reply.writeNoException();
+ return true;
+ }
+
+ case IS_USER_A_MONKEY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ reply.writeInt(isUserAMonkey() ? 1 : 0);
+ reply.writeNoException();
return true;
}
}
@@ -2598,5 +2606,17 @@
reply.recycle();
}
+ public boolean isUserAMonkey() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(IS_USER_A_MONKEY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean res = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/DeviceAdminInfo.java b/core/java/android/app/DeviceAdminInfo.java
index 50b342b..ab9c44f 100644
--- a/core/java/android/app/DeviceAdminInfo.java
+++ b/core/java/android/app/DeviceAdminInfo.java
@@ -50,7 +50,7 @@
/**
* A type of policy that this device admin can use: limit the passwords
- * that the user can select, via {@link DevicePolicyManager#setPasswordMode}
+ * that the user can select, via {@link DevicePolicyManager#setPasswordQuality}
* and {@link DevicePolicyManager#setPasswordMinimumLength}.
*
* <p>To control this policy, the device admin must have a "limit-password"
diff --git a/core/java/android/app/DevicePolicyManager.java b/core/java/android/app/DevicePolicyManager.java
index 779db3a..074a62f 100644
--- a/core/java/android/app/DevicePolicyManager.java
+++ b/core/java/android/app/DevicePolicyManager.java
@@ -88,7 +88,7 @@
/**
* Activity action: have the user enter a new password. This activity
- * should be launched after using {@link #setPasswordMode(ComponentName, int)}
+ * should be launched after using {@link #setPasswordQuality(ComponentName, int)}
* or {@link #setPasswordMinimumLength(ComponentName, int)} to have the
* user enter a new password that meets the current requirements. You can
* use {@link #isActivePasswordSufficient()} to determine whether you need
@@ -149,32 +149,33 @@
}
/**
- * Constant for {@link #setPasswordMode}: the policy has no requirements
- * for the password. Note that mode constants are ordered so that higher
+ * Constant for {@link #setPasswordQuality}: the policy has no requirements
+ * for the password. Note that quality constants are ordered so that higher
* values are more restrictive.
*/
- public static final int PASSWORD_MODE_UNSPECIFIED = 0;
+ public static final int PASSWORD_QUALITY_UNSPECIFIED = 0;
/**
- * Constant for {@link #setPasswordMode}: the policy requires some kind
- * of password, but doesn't care what it is. Note that mode constants
+ * Constant for {@link #setPasswordQuality}: the policy requires some kind
+ * of password, but doesn't care what it is. Note that quality constants
* are ordered so that higher values are more restrictive.
*/
- public static final int PASSWORD_MODE_SOMETHING = 1000;
+ public static final int PASSWORD_QUALITY_SOMETHING = 0x10000;
/**
- * Constant for {@link #setPasswordMode}: the user must have at least a
- * numeric password. Note that mode constants are ordered so that higher
- * values are more restrictive.
+ * Constant for {@link #setPasswordQuality}: the user must have entered a
+ * password containing at least numeric characters. Note that quality
+ * constants are ordered so that higher values are more restrictive.
*/
- public static final int PASSWORD_MODE_NUMERIC = 2000;
+ public static final int PASSWORD_QUALITY_NUMERIC = 0x20000;
/**
- * Constant for {@link #setPasswordMode}: the user must have at least an
- * alphanumeric password. Note that mode constants are ordered so that higher
- * values are more restrictive.
+ * Constant for {@link #setPasswordQuality}: the user must have entered a
+ * password containing at least <em>both></em> numeric <em>and</em>
+ * alphabeter (or other symbol) characters. Note that quality constants are
+ * ordered so that higher values are more restrictive.
*/
- public static final int PASSWORD_MODE_ALPHANUMERIC = 3000;
+ public static final int PASSWORD_QUALITY_ALPHANUMERIC = 0x30000;
/**
* Called by an application that is administering the device to set the
@@ -185,8 +186,8 @@
* take place immediately. To prompt the user for a new password, use
* {@link #ACTION_SET_NEW_PASSWORD} after setting this value.
*
- * <p>Mode constants are ordered so that higher values are more restrictive;
- * thus the highest requested mode constant (between the policy set here,
+ * <p>Quality constants are ordered so that higher values are more restrictive;
+ * thus the highest requested quality constant (between the policy set here,
* the user's preference, and any other considerations) is the one that
* is in effect.
*
@@ -195,14 +196,14 @@
* this method; if it has not, a security exception will be thrown.
*
* @param admin Which {@link DeviceAdmin} this request is associated with.
- * @param mode The new desired mode. One of
- * {@link #PASSWORD_MODE_UNSPECIFIED}, {@link #PASSWORD_MODE_SOMETHING},
- * {@link #PASSWORD_MODE_NUMERIC}, or {@link #PASSWORD_MODE_ALPHANUMERIC}.
+ * @param quality The new desired quality. One of
+ * {@link #PASSWORD_QUALITY_UNSPECIFIED}, {@link #PASSWORD_QUALITY_SOMETHING},
+ * {@link #PASSWORD_QUALITY_NUMERIC}, or {@link #PASSWORD_QUALITY_ALPHANUMERIC}.
*/
- public void setPasswordMode(ComponentName admin, int mode) {
+ public void setPasswordQuality(ComponentName admin, int quality) {
if (mService != null) {
try {
- mService.setPasswordMode(admin, mode);
+ mService.setPasswordQuality(admin, quality);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -210,20 +211,20 @@
}
/**
- * Retrieve the current minimum password mode for all admins
+ * Retrieve the current minimum password quality for all admins
* or a particular one.
* @param admin The name of the admin component to check, or null to aggregate
* all admins.
*/
- public int getPasswordMode(ComponentName admin) {
+ public int getPasswordQuality(ComponentName admin) {
if (mService != null) {
try {
- return mService.getPasswordMode(admin);
+ return mService.getPasswordQuality(admin);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
- return PASSWORD_MODE_UNSPECIFIED;
+ return PASSWORD_QUALITY_UNSPECIFIED;
}
/**
@@ -235,8 +236,8 @@
* 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_MODE_NUMERIC} or {@link #PASSWORD_MODE_ALPHANUMERIC}
- * with {@link #setPasswordMode}.
+ * {@link #PASSWORD_QUALITY_NUMERIC} or {@link #PASSWORD_QUALITY_ALPHANUMERIC}
+ * with {@link #setPasswordQuality}.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to be able to call
@@ -275,18 +276,18 @@
/**
* Return the maximum password length that the device supports for a
- * particular password mode.
+ * particular password quality.
* @param mode The mode being interrogated.
* @return Returns the maximum length that the user can enter.
*/
- public int getPasswordMaximumLength(int mode) {
+ public int getPasswordMaximumLength(int quality) {
// Kind-of arbitrary.
return 16;
}
/**
* Determine whether the current password the user has set is sufficient
- * to meet the policy requirements (mode, minimum length) that have been
+ * to meet the policy requirements (quality, minimum length) that have been
* requested.
*
* <p>The calling device admin must have requested
@@ -368,14 +369,15 @@
}
/**
- * Force a new password on the user. This takes effect immediately. The
- * given password must meet the current password minimum length constraint
- * or it will be rejected. The given password will be accepted regardless
- * of the current password mode, automatically adjusting the password mode
- * higher if needed to meet the requirements of all active administrators.
- * (The string you give here is acceptable for any mode;
- * if it contains only digits, that is still an acceptable alphanumeric
- * password.)
+ * Force a new password on the user. This takes effect immediately.
+ * The given password must be sufficient for the
+ * current password quality and length constraints as returned by
+ * {@link #getPasswordQuality(ComponentName)} and
+ * {@link #getPasswordMinimumLength(ComponentName)}; if it does not meet
+ * these constraints, then it will be rejected and false returned. Note
+ * that the password may be a stronger quality (containing alphanumeric
+ * characters when the requested quality is only numeric), in which case
+ * the currently active quality will be increased to match.
*
* <p>The calling device admin must have requested
* {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call
@@ -531,10 +533,10 @@
/**
* @hide
*/
- public void setActivePasswordState(int mode, int length) {
+ public void setActivePasswordState(int quality, int length) {
if (mService != null) {
try {
- mService.setActivePasswordState(mode, length);
+ mService.setActivePasswordState(quality, length);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 016d465..86f28bf 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -288,6 +288,8 @@
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) throws RemoteException;
+ public boolean isUserAMonkey() throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -450,4 +452,5 @@
int OVERRIDE_PENDING_TRANSITION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+100;
int HANDLE_APPLICATION_WTF_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+101;
int KILL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+102;
+ int IS_USER_A_MONKEY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+103;
}
diff --git a/core/java/android/app/IDevicePolicyManager.aidl b/core/java/android/app/IDevicePolicyManager.aidl
index 8d804f9..ae5c4bf 100644
--- a/core/java/android/app/IDevicePolicyManager.aidl
+++ b/core/java/android/app/IDevicePolicyManager.aidl
@@ -25,8 +25,8 @@
* {@hide}
*/
interface IDevicePolicyManager {
- void setPasswordMode(in ComponentName who, int mode);
- int getPasswordMode(in ComponentName who);
+ void setPasswordQuality(in ComponentName who, int quality);
+ int getPasswordQuality(in ComponentName who);
void setPasswordMinimumLength(in ComponentName who, int length);
int getPasswordMinimumLength(in ComponentName who);
@@ -52,7 +52,7 @@
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result);
void removeActiveAdmin(in ComponentName policyReceiver);
- void setActivePasswordState(int mode, int length);
+ void setActivePasswordState(int quality, int length);
void reportFailedPasswordAttempt();
void reportSuccessfulPasswordAttempt();
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 6347146..f074b80 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -80,9 +80,10 @@
* pin = digit-only password
* password = alphanumeric password
*/
- public static final int MODE_PATTERN = DevicePolicyManager.PASSWORD_MODE_SOMETHING;
- public static final int MODE_PIN = DevicePolicyManager.PASSWORD_MODE_NUMERIC;
- public static final int MODE_PASSWORD = DevicePolicyManager.PASSWORD_MODE_ALPHANUMERIC;
+ public static final int MODE_UNSPECIFIED = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ public static final int MODE_PATTERN = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
+ public static final int MODE_PIN = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
+ public static final int MODE_PASSWORD = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
/**
* The minimum number of dots the user must include in a wrong pattern
@@ -132,13 +133,13 @@
* @return
*/
public int getRequestedPasswordMode() {
- int policyMode = mDevicePolicyManager.getPasswordMode(null);
+ int policyMode = mDevicePolicyManager.getPasswordQuality(null);
switch (policyMode) {
- case DevicePolicyManager.PASSWORD_MODE_ALPHANUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
return MODE_PASSWORD;
- case DevicePolicyManager.PASSWORD_MODE_NUMERIC:
+ case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
return MODE_PIN;
- case DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED:
+ case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
return MODE_PATTERN;
}
return MODE_PATTERN;
@@ -158,16 +159,16 @@
}
public void setActivePasswordState(int mode, int length) {
- int policyMode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED;
+ int policyMode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
switch (mode) {
case MODE_PATTERN:
- policyMode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED;
+ policyMode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
break;
case MODE_PIN:
- policyMode = DevicePolicyManager.PASSWORD_MODE_NUMERIC;
+ policyMode = DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
break;
case MODE_PASSWORD:
- policyMode = DevicePolicyManager.PASSWORD_MODE_ALPHANUMERIC;
+ policyMode = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
break;
}
mDevicePolicyManager.setActivePasswordState(policyMode, length);
@@ -302,7 +303,7 @@
DevicePolicyManager dpm = (DevicePolicyManager)mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
dpm.setActivePasswordState(
- DevicePolicyManager.PASSWORD_MODE_SOMETHING, pattern.size());
+ DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, pattern.size());
}
} catch (FileNotFoundException fnfe) {
// Cant do much, unless we want to fail over to using the settings provider
@@ -314,7 +315,65 @@
}
/**
- * Save a lock password.
+ * Compare the given password and mode, ensuring that the password meets
+ * the mode and returning the minimum mode needed for the given password.
+ * @param password The password to be used.
+ * @param reqMode The desired password mode.
+ * @return Returns {@link #MODE_UNSPECIFIED} if the password is not
+ * good enough for the given mode. Otherwise, returns either the original
+ * reqMode or something better if that is needed for the given password.
+ */
+ static public int adjustPasswordMode(String password, int reqMode) {
+ boolean hasDigit = false;
+ boolean hasNonDigit = false;
+ final int len = password.length();
+ for (int i = 0; i < len; i++) {
+ if (Character.isDigit(password.charAt(i))) {
+ hasDigit = true;
+ } else {
+ hasNonDigit = true;
+ }
+ }
+
+ // First check if it is sufficient.
+ switch (reqMode) {
+ case MODE_PASSWORD: {
+ if (!hasDigit || !hasNonDigit) {
+ return MODE_UNSPECIFIED;
+ }
+ } break;
+
+ case MODE_PIN:
+ case MODE_PATTERN: {
+ // Whatever we have is acceptable; we may need to promote the
+ // mode later.
+ } break;
+
+ default:
+ // If it isn't a mode we specifically know, then fail fast.
+ Log.w(TAG, "adjustPasswordMode: unknown mode " + reqMode);
+ return MODE_UNSPECIFIED;
+ }
+
+ // Do we need to promote?
+ if (hasNonDigit) {
+ if (reqMode < MODE_PASSWORD) {
+ reqMode = MODE_PASSWORD;
+ }
+ }
+ if (hasDigit) {
+ if (reqMode < MODE_PIN) {
+ reqMode = MODE_PIN;
+ }
+ }
+
+ return reqMode;
+ }
+
+ /**
+ * Save a lock password. Does not ensure that the pattern is as good
+ * as the requested mode, but will adjust the mode to be as good as the
+ * pattern.
* @param password The password to save
*/
public void saveLockPassword(String password, int mode) {
@@ -331,9 +390,9 @@
}
raf.close();
if (password != null) {
- int textMode = TextUtils.isDigitsOnly(password) ? MODE_PIN : MODE_PASSWORD;
- if (textMode > mode) {
- mode = textMode;
+ int finalMode = adjustPasswordMode(password, mode);
+ if (mode < finalMode) {
+ mode = finalMode;
}
setLong(PASSWORD_TYPE_KEY, mode);
DevicePolicyManager dpm = (DevicePolicyManager)mContext.getSystemService(
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 979955c..015b487 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -71,7 +71,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 47;
+ private static final int DATABASE_VERSION = 48;
private Context mContext;
@@ -595,8 +595,23 @@
upgradeVersion = 47;
}
+
+ if (upgradeVersion == 47) {
+ /*
+ * The password mode constants have changed again; reset back to no
+ * password.
+ */
+ db.beginTransaction();
+ try {
+ db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';");
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ upgradeVersion = 48;
+ }
- if (upgradeVersion != currentVersion) {
+ if (upgradeVersion != currentVersion) {
Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
+ ", must wipe the settings provider");
db.execSQL("DROP TABLE IF EXISTS system");
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 17a3ab8..e4ee4ae 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -64,7 +64,7 @@
IPowerManager mIPowerManager;
- int mActivePasswordMode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED;
+ int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
int mActivePasswordLength = 0;
int mFailedPasswordAttempts = 0;
@@ -76,7 +76,7 @@
static class ActiveAdmin {
final DeviceAdminInfo info;
- int passwordMode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED;
+ int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
int minimumPasswordLength = 0;
long maximumTimeToUnlock = 0;
int maximumFailedPasswordsForWipe = 0;
@@ -89,17 +89,17 @@
void writeToXml(XmlSerializer out)
throws IllegalArgumentException, IllegalStateException, IOException {
- if (passwordMode != DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED) {
- out.startTag(null, "password-mode");
- out.attribute(null, "value", Integer.toString(passwordMode));
- out.endTag(null, "password-mode");
+ if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+ out.startTag(null, "password-quality");
+ out.attribute(null, "value", Integer.toString(passwordQuality));
+ out.endTag(null, "password-quality");
if (minimumPasswordLength > 0) {
out.startTag(null, "min-password-length");
out.attribute(null, "value", Integer.toString(minimumPasswordLength));
out.endTag(null, "mn-password-length");
}
}
- if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED) {
+ if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
out.startTag(null, "max-time-to-unlock");
out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
out.endTag(null, "max-time-to-unlock");
@@ -121,8 +121,8 @@
continue;
}
String tag = parser.getName();
- if ("password-mode".equals(tag)) {
- passwordMode = Integer.parseInt(
+ if ("password-quality".equals(tag)) {
+ passwordQuality = Integer.parseInt(
parser.getAttributeValue(null, "value"));
} else if ("min-password-length".equals(tag)) {
minimumPasswordLength = Integer.parseInt(
@@ -435,34 +435,34 @@
}
}
- public void setPasswordMode(ComponentName who, int mode) {
+ public void setPasswordQuality(ComponentName who, int mode) {
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
}
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.passwordMode != mode) {
- ap.passwordMode = mode;
+ if (ap.passwordQuality != mode) {
+ ap.passwordQuality = mode;
saveSettingsLocked();
}
}
}
- public int getPasswordMode(ComponentName who) {
+ public int getPasswordQuality(ComponentName who) {
synchronized (this) {
- int mode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED;
+ int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
if (who != null) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(who);
- return admin != null ? admin.passwordMode : mode;
+ return admin != null ? admin.passwordQuality : mode;
}
final int N = mAdminList.size();
for (int i=0; i<N; i++) {
ActiveAdmin admin = mAdminList.get(i);
- if (mode < admin.passwordMode) {
- mode = admin.passwordMode;
+ if (mode < admin.passwordQuality) {
+ mode = admin.passwordQuality;
}
}
return mode;
@@ -509,7 +509,7 @@
// so try to retrieve it to check that the caller is one.
getActiveAdminForCallerLocked(null,
DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- return mActivePasswordMode >= getPasswordMode(null)
+ return mActivePasswordQuality >= getPasswordQuality(null)
&& mActivePasswordLength >= getPasswordMinimumLength(null);
}
}
@@ -563,14 +563,24 @@
}
public boolean resetPassword(String password) {
- int mode;
+ int quality;
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_RESET_PASSWORD);
- mode = getPasswordMode(null);
- if (password.length() < getPasswordMinimumLength(null)) {
+ quality = getPasswordQuality(null);
+ if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+ int adjQuality = LockPatternUtils.adjustPasswordMode(password, quality);
+ if (adjQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
+ Log.w(TAG, "resetPassword: password does not meet quality " + quality);
+ return false;
+ }
+ quality = adjQuality;
+ }
+ int length = getPasswordMinimumLength(null);
+ if (password.length() < length) {
+ Log.w(TAG, "resetPassword: password does not meet length " + length);
return false;
}
}
@@ -580,7 +590,7 @@
long ident = Binder.clearCallingIdentity();
try {
LockPatternUtils utils = new LockPatternUtils(mContext);
- utils.saveLockPassword(password, mode);
+ utils.saveLockPassword(password, quality);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -709,16 +719,16 @@
}
}
- public void setActivePasswordState(int mode, int length) {
+ public void setActivePasswordState(int quality, int length) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
synchronized (this) {
- if (mActivePasswordMode != mode || mActivePasswordLength != length
+ if (mActivePasswordQuality != quality || mActivePasswordLength != length
|| mFailedPasswordAttempts != 0) {
long ident = Binder.clearCallingIdentity();
try {
- mActivePasswordMode = mode;
+ mActivePasswordQuality = quality;
mActivePasswordLength = length;
if (mFailedPasswordAttempts != 0) {
mFailedPasswordAttempts = 0;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c2c6e76..b723dcd 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8081,6 +8081,14 @@
}
}
+ public boolean isUserAMonkey() {
+ // For now the fact that there is a controller implies
+ // we have a monkey.
+ synchronized (this) {
+ return mController != null;
+ }
+ }
+
public void registerActivityWatcher(IActivityWatcher watcher) {
mWatchers.register(watcher);
}