diff options
-rw-r--r-- | api/current.xml | 33 | ||||
-rw-r--r-- | core/java/android/app/ActivityManager.java | 11 | ||||
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 20 | ||||
-rw-r--r-- | core/java/android/app/DeviceAdminInfo.java | 2 | ||||
-rw-r--r-- | core/java/android/app/DevicePolicyManager.java | 84 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 3 | ||||
-rw-r--r-- | core/java/android/app/IDevicePolicyManager.aidl | 6 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/LockPatternUtils.java | 91 | ||||
-rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java | 19 | ||||
-rw-r--r-- | services/java/com/android/server/DevicePolicyManagerService.java | 60 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 8 |
11 files changed, 238 insertions, 99 deletions
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 @@ public class ActivityManager { 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 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM 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 @@ class ActivityManagerProxy implements IActivityManager 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 @@ public final class DeviceAdminInfo implements Parcelable { /** * 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 @@ public class DevicePolicyManager { /** * 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 @@ public class DevicePolicyManager { } /** - * 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 @@ public class DevicePolicyManager { * 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 @@ public class DevicePolicyManager { * 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 @@ public class DevicePolicyManager { } /** - * 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 @@ 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_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 @@ public class DevicePolicyManager { /** * 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 @@ public class DevicePolicyManager { } /** - * 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 @@ public class DevicePolicyManager { /** * @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 interface IActivityManager extends IInterface { 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 @@ public interface IActivityManager extends IInterface { 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 @@ import android.os.RemoteCallback; * {@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 @@ interface IDevicePolicyManager { 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 @@ public class LockPatternUtils { * 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 @@ public class LockPatternUtils { * @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 class LockPatternUtils { } 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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { } /** - * 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 @@ public class LockPatternUtils { } 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 @@ public class DatabaseHelper extends SQLiteOpenHelper { // 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 @@ public class DatabaseHelper extends SQLiteOpenHelper { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { IPowerManager mIPowerManager; - int mActivePasswordMode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED; + int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; int mActivePasswordLength = 0; int mFailedPasswordAttempts = 0; @@ -76,7 +76,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // 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 class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } 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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 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 class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - 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 final class ActivityManagerService extends ActivityManagerNative implemen } } + 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); } |