diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-01-20 13:37:26 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2010-01-21 14:30:57 -0800 |
commit | df83afaf299666e99c519aa86e7e082b7c116e95 (patch) | |
tree | 65480fb272324aee6613d0449d40d5e078a700a8 | |
parent | 04ce08f34e39928a5b8e9ea59134f255c9ff08f6 (diff) | |
download | frameworks_base-df83afaf299666e99c519aa86e7e082b7c116e95.zip frameworks_base-df83afaf299666e99c519aa86e7e082b7c116e95.tar.gz frameworks_base-df83afaf299666e99c519aa86e7e082b7c116e95.tar.bz2 |
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.
-rw-r--r-- | api/current.xml | 97 | ||||
-rw-r--r-- | core/java/android/app/DevicePolicyManager.java | 114 | ||||
-rw-r--r-- | core/java/android/app/IDevicePolicyManager.aidl | 7 | ||||
-rw-r--r-- | core/java/android/os/IPowerManager.aidl | 1 | ||||
-rw-r--r-- | core/java/com/android/internal/widget/LockPatternUtils.java | 58 | ||||
-rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java | 17 | ||||
-rw-r--r-- | services/java/com/android/server/DevicePolicyManagerService.java | 110 | ||||
-rw-r--r-- | services/java/com/android/server/PowerManagerService.java | 23 |
8 files changed, 307 insertions, 120 deletions
diff --git a/api/current.xml b/api/current.xml index 01ff582..689f5dd 100644 --- a/api/current.xml +++ b/api/current.xml @@ -20208,7 +20208,7 @@ deprecated="not deprecated" visibility="public" > -<method name="getActiveMinimumPasswordLength" +<method name="getCurrentFailedPasswordAttempts" return="int" abstract="false" native="false" @@ -20219,8 +20219,8 @@ visibility="public" > </method> -<method name="getActivePasswordMode" - return="int" +<method name="getMaximumTimeToLock" + return="long" abstract="false" native="false" synchronized="false" @@ -20230,7 +20230,7 @@ visibility="public" > </method> -<method name="getCurrentFailedPasswordAttempts" +<method name="getMinimumPasswordLength" return="int" abstract="false" native="false" @@ -20241,8 +20241,8 @@ visibility="public" > </method> -<method name="getMaximumTimeToLock" - return="long" +<method name="getPasswordMode" + return="int" abstract="false" native="false" synchronized="false" @@ -20252,8 +20252,8 @@ visibility="public" > </method> -<method name="getMinimumPasswordLength" - return="int" +<method name="isActivePasswordSufficient" + return="boolean" abstract="false" native="false" synchronized="false" @@ -20263,8 +20263,8 @@ visibility="public" > </method> -<method name="getPasswordMode" - return="int" +<method name="isAdminActive" + return="boolean" abstract="false" native="false" synchronized="false" @@ -20273,9 +20273,11 @@ deprecated="not deprecated" visibility="public" > +<parameter name="who" type="android.content.ComponentName"> +</parameter> </method> -<method name="isAdminActive" - return="boolean" +<method name="lockNow" + return="void" abstract="false" native="false" synchronized="false" @@ -20284,8 +20286,6 @@ deprecated="not deprecated" visibility="public" > -<parameter name="who" type="android.content.ComponentName"> -</parameter> </method> <method name="removeActiveAdmin" return="void" @@ -20300,6 +20300,19 @@ <parameter name="who" type="android.content.ComponentName"> </parameter> </method> +<method name="resetPassword" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="password" type="java.lang.String"> +</parameter> +</method> <method name="setMaximumTimeToLock" return="void" abstract="false" @@ -20395,7 +20408,7 @@ type="int" transient="false" volatile="false" - value="2000" + value="3000" static="true" final="true" deprecated="not deprecated" @@ -20406,40 +20419,29 @@ type="int" transient="false" volatile="false" - value="1000" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> -<field name="PASSWORD_MODE_UNSPECIFIED" - type="int" - transient="false" - volatile="false" - value="0" + value="2000" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="WIPE_EXTERNAL_STORAGE" +<field name="PASSWORD_MODE_SOMETHING" type="int" transient="false" volatile="false" - value="2" + value="1000" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="WIPE_LOW_LEVEL_FORMAT" +<field name="PASSWORD_MODE_UNSPECIFIED" type="int" transient="false" volatile="false" - value="1" + value="0" static="true" final="true" deprecated="not deprecated" @@ -53548,6 +53550,17 @@ <parameter name="stroke" type="android.gesture.GestureStroke"> </parameter> </method> +<method name="clone" + return="java.lang.Object" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="describeContents" return="int" abstract="false" @@ -54737,6 +54750,17 @@ <parameter name="t" type="long"> </parameter> </constructor> +<method name="clone" + return="java.lang.Object" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <field name="timestamp" type="long" transient="false" @@ -55061,6 +55085,17 @@ visibility="public" > </method> +<method name="clone" + return="java.lang.Object" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="computeOrientedBoundingBox" return="android.gesture.OrientedBoundingBox" abstract="false" diff --git a/core/java/android/app/DevicePolicyManager.java b/core/java/android/app/DevicePolicyManager.java index 4fdfe0a..538ba5b 100644 --- a/core/java/android/app/DevicePolicyManager.java +++ b/core/java/android/app/DevicePolicyManager.java @@ -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 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_SOMETHING = 1000; + + /** * Constant for {@link #setPasswordMode}: the user must have at least a - * numeric password. + * numeric password. 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_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) { @@ -178,21 +194,6 @@ public class DevicePolicyManager { } /** - * 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 * will not be able to enter a new password that is not at least as @@ -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) { diff --git a/core/java/android/app/IDevicePolicyManager.aidl b/core/java/android/app/IDevicePolicyManager.aidl index f62647f..7e38194 100644 --- a/core/java/android/app/IDevicePolicyManager.aidl +++ b/core/java/android/app/IDevicePolicyManager.aidl @@ -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); diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 23762ca..b5408ae 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -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); diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 9f7a370..66c0719 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -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(); } @@ -279,6 +273,16 @@ public class LockPatternUtils { } /** + * 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); } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 89d75b7..979955c 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 = 46; + private static final int DATABASE_VERSION = 47; private Context mContext; @@ -580,6 +580,21 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 46; } + if (upgradeVersion == 46) { + /* + * The password mode constants have changed; reset back to no + * password. + */ + db.beginTransaction(); + try { + db.execSQL("DELETE FROM system WHERE name='lockscreen.password_type';"); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + upgradeVersion = 47; + } + if (upgradeVersion != currentVersion) { Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java index e13ddc8..fd42538 100644 --- a/services/java/com/android/server/DevicePolicyManagerService.java +++ b/services/java/com/android/server/DevicePolicyManagerService.java @@ -17,6 +17,7 @@ package com.android.server; import com.android.common.FastXmlSerializer; +import com.android.internal.widget.LockPatternUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -27,11 +28,19 @@ import android.app.DeviceAdminInfo; import android.app.DevicePolicyManager; import android.app.IDevicePolicyManager; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Binder; +import android.os.IBinder; +import android.os.IPowerManager; +import android.os.PowerManager; +import android.os.RecoverySystem; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.provider.Settings; import android.util.Log; import android.util.Xml; @@ -49,6 +58,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private final Context mContext; + IPowerManager mIPowerManager; + int mActivePasswordMode = DevicePolicyManager.PASSWORD_MODE_UNSPECIFIED; int mActivePasswordLength = 0; int mFailedPasswordAttempts = 0; @@ -75,8 +86,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext = context; } + private IPowerManager getIPowerManager() { + if (mIPowerManager == null) { + IBinder b = ServiceManager.getService(Context.POWER_SERVICE); + mIPowerManager = IPowerManager.Stub.asInterface(b); + } + return mIPowerManager; + } + ActiveAdmin getActiveAdminForCallerLocked(ComponentName who) throws SecurityException { - if (mActiveAdmin != null && mActiveAdmin.getUid() == Binder.getCallingPid()) { + if (mActiveAdmin != null && mActiveAdmin.getUid() == Binder.getCallingUid()) { if (who != null) { if (!who.getPackageName().equals(mActiveAdmin.info.getActivityInfo().packageName) || !who.getClassName().equals(mActiveAdmin.info.getActivityInfo().name)) { @@ -258,6 +277,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!success) { Log.w(TAG, "No valid start tag found in policies file"); } + + long timeMs = getMaximumTimeToLock(); + if (timeMs <= 0) { + timeMs = Integer.MAX_VALUE; + } + try { + getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); + } catch (RemoteException e) { + Log.w(TAG, "Failure talking with power manager", e); + } + } public void systemReady() { @@ -335,15 +365,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - public int getActivePasswordMode() { - 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); - return mActivePasswordMode; - } - } - public void setMinimumPasswordLength(ComponentName who, int length) { synchronized (this) { if (who == null) { @@ -363,12 +384,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - public int getActiveMinimumPasswordLength() { + 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); - return mActivePasswordLength; + return mActivePasswordMode >= getPasswordMode() + && mActivePasswordLength >= getMinimumPasswordLength(); } } @@ -381,6 +403,31 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + public boolean resetPassword(String password) { + int mode; + 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); + mode = getPasswordMode(); + if (password.length() < getMinimumPasswordLength()) { + return false; + } + } + + // Don't do this with the lock held, because it is going to call + // back in to the service. + long ident = Binder.clearCallingIdentity(); + try { + LockPatternUtils utils = new LockPatternUtils(mContext); + utils.saveLockPassword(password, mode); + } finally { + Binder.restoreCallingIdentity(ident); + } + + return true; + } + public void setMaximumTimeToLock(ComponentName who, long timeMs) { synchronized (this) { if (who == null) { @@ -389,7 +436,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ActiveAdmin ap = getActiveAdminForCallerLocked(who); if (ap.maximumTimeToUnlock != timeMs) { ap.maximumTimeToUnlock = timeMs; - saveSettingsLocked(); + + long ident = Binder.clearCallingIdentity(); + try { + saveSettingsLocked(); + if (timeMs <= 0) { + timeMs = Integer.MAX_VALUE; + } + try { + getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); + } catch (RemoteException e) { + Log.w(TAG, "Failure talking with power manager", e); + } + } finally { + Binder.restoreCallingIdentity(ident); + } } } } @@ -400,17 +461,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + public void lockNow() { + 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); + // STOPSHIP need to implement. + } + } + public void wipeData(int flags) { 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); - long ident = Binder.clearCallingIdentity(); - try { - Log.w(TAG, "*************** WIPE DATA HERE"); - } finally { - Binder.restoreCallingIdentity(ident); - } + } + long ident = Binder.clearCallingIdentity(); + try { + RecoverySystem.rebootWipeUserData(mContext); + } catch (IOException e) { + Log.w(TAG, "Failed requesting data wipe", e); + } finally { + Binder.restoreCallingIdentity(ident); } } diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java index bf6996c..f106fc3 100644 --- a/services/java/com/android/server/PowerManagerService.java +++ b/services/java/com/android/server/PowerManagerService.java @@ -169,7 +169,8 @@ class PowerManagerService extends IPowerManager.Stub private boolean mProximitySensorActive = false; private int mProximityPendingValue = -1; // -1 == nothing, 0 == inactive, 1 == active private long mLastProximityEventTime; - private int mTotalDelaySetting; + private int mScreenOffTimeoutSetting; + private int mMaximumScreenOffTimeout = Integer.MAX_VALUE; private int mKeylightDelay; private int mDimDelay; private int mScreenOffDelay; @@ -378,6 +379,16 @@ class PowerManagerService extends IPowerManager.Stub Settings.System.STAY_ON_WHILE_PLUGGED_IN, val); } + public void setMaximumScreenOffTimeount(int timeMs) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.WRITE_SECURE_SETTINGS, null); + synchronized (mLocks) { + mMaximumScreenOffTimeout = timeMs; + // recalculate everything + setScreenOffTimeoutsLocked(); + } + } + private class SettingsObserver implements Observer { private int getInt(String name) { return mSettings.getValues(name).getAsInteger(Settings.System.VALUE); @@ -390,7 +401,7 @@ class PowerManagerService extends IPowerManager.Stub updateWakeLockLocked(); // SCREEN_OFF_TIMEOUT - mTotalDelaySetting = getInt(SCREEN_OFF_TIMEOUT); + mScreenOffTimeoutSetting = getInt(SCREEN_OFF_TIMEOUT); // DIM_SCREEN //mDimScreen = getInt(DIM_SCREEN) != 0; @@ -935,7 +946,8 @@ class PowerManagerService extends IPowerManager.Stub pw.println(" mPreventScreenOn=" + mPreventScreenOn + " mScreenBrightnessOverride=" + mScreenBrightnessOverride + " mButtonBrightnessOverride=" + mButtonBrightnessOverride); - pw.println(" mTotalDelaySetting=" + mTotalDelaySetting); + pw.println(" mScreenOffTimeoutSetting=" + mScreenOffTimeoutSetting + + " mMaximumScreenOffTimeout=" + mMaximumScreenOffTimeout); pw.println(" mLastScreenOnTime=" + mLastScreenOnTime); pw.println(" mBroadcastWakeLock=" + mBroadcastWakeLock); pw.println(" mStayOnWhilePluggedInScreenDimLock=" + mStayOnWhilePluggedInScreenDimLock); @@ -2285,7 +2297,10 @@ class PowerManagerService extends IPowerManager.Stub mDimDelay = -1; mScreenOffDelay = 0; } else { - int totalDelay = mTotalDelaySetting; + int totalDelay = mScreenOffTimeoutSetting; + if (totalDelay > mMaximumScreenOffTimeout) { + totalDelay = mMaximumScreenOffTimeout; + } mKeylightDelay = LONG_KEYLIGHT_DELAY; if (totalDelay < 0) { mScreenOffDelay = Integer.MAX_VALUE; |