summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-01-20 13:37:26 -0800
committerDianne Hackborn <hackbod@google.com>2010-01-21 14:30:57 -0800
commitdf83afaf299666e99c519aa86e7e082b7c116e95 (patch)
tree65480fb272324aee6613d0449d40d5e078a700a8
parent04ce08f34e39928a5b8e9ea59134f255c9ff08f6 (diff)
downloadframeworks_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.xml97
-rw-r--r--core/java/android/app/DevicePolicyManager.java114
-rw-r--r--core/java/android/app/IDevicePolicyManager.aidl7
-rw-r--r--core/java/android/os/IPowerManager.aidl1
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java58
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java17
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java110
-rw-r--r--services/java/com/android/server/PowerManagerService.java23
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;