More device policy manager / admin work.

Update API with some new features, re-arrange how you check for valid
passwords, and start hooking up the back-end implementation.
This commit is contained in:
Dianne Hackborn
2010-01-20 13:37:26 -08:00
parent 04ce08f34e
commit df83afaf29
8 changed files with 322 additions and 135 deletions

View File

@@ -79,9 +79,10 @@ public class DevicePolicyManager {
* Activity action: have the user enter a new password. This activity
* should be launched after using {@link #setPasswordMode(ComponentName, int)}
* or {@link #setMinimumPasswordLength(ComponentName, int)} to have the
* user enter a new password that meets the current requirements. If the
* current password is sufficient, the activity will exit immediately without
* being displayed to the user. Upon receiving a result from this activity,
* user enter a new password that meets the current requirements. You can
* use {@link #isActivePasswordSufficient()} to determine whether you need
* to have the user select a new password in order to meet the current
* constraints. Upon being resumed from this activity,
* you can check the new password characteristics to see if they are
* sufficient.
*/
@@ -122,21 +123,31 @@ public class DevicePolicyManager {
/**
* Constant for {@link #setPasswordMode}: the policy has no requirements
* for the password.
* for the password. Note that mode constants are ordered so that higher
* values are more restrictive.
*/
public static final int PASSWORD_MODE_UNSPECIFIED = 0;
/**
* Constant for {@link #setPasswordMode}: the user must have at least a
* numeric password.
* Constant for {@link #setPasswordMode}: the policy requires some kind
* of password, but doesn't care what it is. Note that mode constants
* are ordered so that higher values are more restrictive.
*/
public static final int PASSWORD_MODE_NUMERIC = 1000;
public static final int PASSWORD_MODE_SOMETHING = 1000;
/**
* 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.
*/
public static final int PASSWORD_MODE_NUMERIC = 2000;
/**
* Constant for {@link #setPasswordMode}: the user must have at least an
* alphanumeric password.
* alphanumeric password. Note that mode constants are ordered so that higher
* values are more restrictive.
*/
public static final int PASSWORD_MODE_ALPHANUMERIC = 2000;
public static final int PASSWORD_MODE_ALPHANUMERIC = 3000;
/**
* Called by an application that is administering the device to set the
@@ -147,10 +158,15 @@ 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,
* the user's preference, and any other considerations) is the one that
* is in effect.
*
* @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_NUMERIC},
* or {@link #PASSWORD_MODE_ALPHANUMERIC}.
* {@link #PASSWORD_MODE_UNSPECIFIED}, {@link #PASSWORD_MODE_SOMETHING},
* {@link #PASSWORD_MODE_NUMERIC}, or {@link #PASSWORD_MODE_ALPHANUMERIC}.
*/
public void setPasswordMode(ComponentName admin, int mode) {
if (mService != null) {
@@ -177,21 +193,6 @@ public class DevicePolicyManager {
return PASSWORD_MODE_UNSPECIFIED;
}
/**
* Retrieve the password mode associated with the last password the
* user selected.
*/
public int getActivePasswordMode() {
if (mService != null) {
try {
return mService.getActivePasswordMode();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return PASSWORD_MODE_UNSPECIFIED;
}
/**
* Called by an application that is administering the device to set the
* minimum allowed password length. After setting this, the user
@@ -234,18 +235,22 @@ public class DevicePolicyManager {
}
/**
* Retrieve the password length associated with the last password the
* user selected.
* Determine whether the current password the user has set is sufficient
* to meet the policy requirements (mode, minimum length) that have been
* requested.
*
* @return Returns true if the password meets the current requirements,
* else false.
*/
public int getActiveMinimumPasswordLength() {
public boolean isActivePasswordSufficient() {
if (mService != null) {
try {
return mService.getActiveMinimumPasswordLength();
return mService.isActivePasswordSufficient();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return 0;
return false;
}
/**
@@ -262,6 +267,30 @@ public class DevicePolicyManager {
}
return -1;
}
/**
* 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. (The string you give here is acceptable for any mode;
* if it contains only digits, that is still an acceptable alphanumeric
* password.)
*
* @param password The new password for the user.
* @return Returns true if the password was applied, or false if it is
* not acceptable for the current constraints.
*/
public boolean resetPassword(String password) {
if (mService != null) {
try {
return mService.resetPassword(password);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
return false;
}
/**
* Called by an application that is administering the device to set the
@@ -298,22 +327,25 @@ public class DevicePolicyManager {
}
/**
* Constant for {@link #wipeData}: perform a low-level format of data
* storage.
* Make the device lock immediately, as if the lock screen timeout has
* expired at the point of this call.
*/
public static final int WIPE_LOW_LEVEL_FORMAT = 0x0001;
/**
* Constant for {@link #wipeData}: also wipe any external storage.
*/
public static final int WIPE_EXTERNAL_STORAGE = 0x0002;
public void lockNow() {
if (mService != null) {
try {
mService.lockNow();
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
}
}
/**
* Ask the user date be wiped. This will cause the device to reboot,
* erasing all user data while next booting up.
* erasing all user data while next booting up. External storage such
* as SD cards will not be erased.
*
* @param flags Bit mask of additional options: currently
* {@link #WIPE_LOW_LEVEL_FORMAT} and {@link #WIPE_EXTERNAL_STORAGE}.
* @param flags Bit mask of additional options: currently must be 0.
*/
public void wipeData(int flags) {
if (mService != null) {

View File

@@ -26,17 +26,20 @@ import android.content.ComponentName;
interface IDevicePolicyManager {
void setPasswordMode(in ComponentName who, int mode);
int getPasswordMode();
int getActivePasswordMode();
void setMinimumPasswordLength(in ComponentName who, int length);
int getMinimumPasswordLength();
int getActiveMinimumPasswordLength();
boolean isActivePasswordSufficient();
int getCurrentFailedPasswordAttempts();
boolean resetPassword(String password);
void setMaximumTimeToLock(in ComponentName who, long timeMs);
long getMaximumTimeToLock();
void lockNow();
void wipeData(int flags);
void setActiveAdmin(in ComponentName policyReceiver);

View File

@@ -28,6 +28,7 @@ interface IPowerManager
void setPokeLock(int pokey, IBinder lock, String tag);
int getSupportedWakeLockFlags();
void setStayOnSetting(int val);
void setMaximumScreenOffTimeount(int timeMs);
void preventScreenOn(boolean prevent);
boolean isScreenOn();
void reboot(String reason);

View File

@@ -79,9 +79,9 @@ public class LockPatternUtils {
* pin = digit-only password
* password = alphanumeric password
*/
public static final int MODE_PATTERN = 0;
public static final int MODE_PIN = 1;
public static final int MODE_PASSWORD = 2;
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;
/**
* The minimum number of dots the user must include in a wrong pattern
@@ -95,6 +95,7 @@ public class LockPatternUtils {
private final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen";
public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type";
private final Context mContext;
private final ContentResolver mContentResolver;
private DevicePolicyManager mDevicePolicyManager;
private static String sLockPatternFilename;
@@ -104,6 +105,7 @@ public class LockPatternUtils {
* @param contentResolver Used to look up and save settings.
*/
public LockPatternUtils(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
mDevicePolicyManager =
(DevicePolicyManager)context.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -126,10 +128,6 @@ public class LockPatternUtils {
return mDevicePolicyManager.getMinimumPasswordLength();
}
public int getActiveMinimumPasswordLength() {
return mDevicePolicyManager.getActiveMinimumPasswordLength();
}
/**
* Gets the device policy password mode. If the mode is non-specific, returns
* MODE_PATTERN which allows the user to choose anything.
@@ -154,10 +152,6 @@ public class LockPatternUtils {
*
* @return
*/
public int getActivePasswordMode() {
return mDevicePolicyManager.getActivePasswordMode();
}
public void reportFailedPasswordAttempt() {
mDevicePolicyManager.reportFailedPasswordAttempt();
}
@@ -278,6 +272,16 @@ public class LockPatternUtils {
return getBoolean(PATTERN_EVER_CHOSEN_KEY);
}
/**
* Clear any lock pattern or password.
*/
public void clearLock() {
saveLockPassword(null, LockPatternUtils.MODE_PATTERN);
setLockPatternEnabled(false);
saveLockPattern(null);
setLong(PASSWORD_TYPE_KEY, MODE_PATTERN);
}
/**
* Save a lock pattern.
* @param pattern The new pattern to save.
@@ -295,11 +299,13 @@ public class LockPatternUtils {
raf.write(hash, 0, hash.length);
}
raf.close();
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
setLong(PASSWORD_TYPE_KEY, MODE_PATTERN);
if (pattern != null && isDevicePolicyActive()) {
setActivePasswordState(DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED,
pattern.size());
if (pattern != null) {
setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
setLong(PASSWORD_TYPE_KEY, MODE_PATTERN);
DevicePolicyManager dpm = (DevicePolicyManager)mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
dpm.setActivePasswordState(
DevicePolicyManager.PASSWORD_MODE_SOMETHING, pattern.size());
}
} catch (FileNotFoundException fnfe) {
// Cant do much, unless we want to fail over to using the settings provider
@@ -314,9 +320,8 @@ public class LockPatternUtils {
* Save a lock password.
* @param password The password to save
*/
public void saveLockPassword(String password) {
public void saveLockPassword(String password, int mode) {
// Compute the hash
boolean numericHint = password != null ? TextUtils.isDigitsOnly(password) : false;
final byte[] hash = LockPatternUtils.passwordToHash(password);
try {
// Write the hash to file
@@ -328,10 +333,15 @@ public class LockPatternUtils {
raf.write(hash, 0, hash.length);
}
raf.close();
setLong(PASSWORD_TYPE_KEY, numericHint ? MODE_PIN : MODE_PASSWORD);
if (password != null && isDevicePolicyActive()) {
setActivePasswordState(numericHint ? DevicePolicyManager.PASSWORD_MODE_NUMERIC
: DevicePolicyManager.PASSWORD_MODE_ALPHANUMERIC, password.length());
if (password != null) {
int textMode = TextUtils.isDigitsOnly(password) ? MODE_PIN : MODE_PASSWORD;
if (textMode > mode) {
mode = textMode;
}
setLong(PASSWORD_TYPE_KEY, mode);
DevicePolicyManager dpm = (DevicePolicyManager)mContext.getSystemService(
Context.DEVICE_POLICY_SERVICE);
dpm.setActivePasswordState(mode, password.length());
}
} catch (FileNotFoundException fnfe) {
// Cant do much, unless we want to fail over to using the settings provider
@@ -554,6 +564,7 @@ public class LockPatternUtils {
}
private boolean getBoolean(String systemSettingKey) {
// STOPSHIP: these need to be moved to secure settings!
return 1 ==
android.provider.Settings.System.getInt(
mContentResolver,
@@ -561,6 +572,7 @@ public class LockPatternUtils {
}
private void setBoolean(String systemSettingKey, boolean enabled) {
// STOPSHIP: these need to be moved to secure settings!
android.provider.Settings.System.putInt(
mContentResolver,
systemSettingKey,
@@ -568,10 +580,12 @@ public class LockPatternUtils {
}
private long getLong(String systemSettingKey, long def) {
// STOPSHIP: these need to be moved to secure settings!
return android.provider.Settings.System.getLong(mContentResolver, systemSettingKey, def);
}
private void setLong(String systemSettingKey, long value) {
// STOPSHIP: these need to be moved to secure settings!
android.provider.Settings.System.putLong(mContentResolver, systemSettingKey, value);
}