You can optionally include the {@link #EXTRA_ADD_EXPLANATION}
* field to provide the user with additional explanation (in addition
* to your component's description) about what is being added.
- *
- * Note: the current platform can only have one device administrator
- * active at a time. If you make this request while there is already
- * an active administrator, this new request will be canceled automatically.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_ADD_DEVICE_ADMIN
@@ -111,7 +108,7 @@ public class DevicePolicyManager {
public boolean isAdminActive(ComponentName who) {
if (mService != null) {
try {
- return who.equals(mService.getActiveAdmin());
+ return mService.isAdminActive(who);
} catch (RemoteException e) {
Log.w(TAG, "Failed talking with device policy service", e);
}
@@ -119,6 +116,22 @@ public class DevicePolicyManager {
return false;
}
+ /**
+ * Return a list of all currently active device administrator's component
+ * names. Note that if there are no administrators than null may be
+ * returned.
+ */
+ public List getActiveAdmins() {
+ if (mService != null) {
+ try {
+ return mService.getActiveAdmins();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return null;
+ }
+
/**
* Remove a current administration component. This can only be called
* by the application that owns the administration component; if you
@@ -442,26 +455,7 @@ public class DevicePolicyManager {
/**
* @hide
*/
- public ComponentName getActiveAdmin() {
- if (mService != null) {
- try {
- return mService.getActiveAdmin();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed talking with device policy service", e);
- }
- }
- return null;
- }
-
- /**
- * @hide
- */
- public DeviceAdminInfo getActiveAdminInfo() {
- ComponentName cn = getActiveAdmin();
- if (cn == null) {
- return null;
- }
-
+ public DeviceAdminInfo getAdminInfo(ComponentName cn) {
ActivityInfo ai;
try {
ai = mContext.getPackageManager().getReceiverInfo(cn,
diff --git a/core/java/android/app/IDevicePolicyManager.aidl b/core/java/android/app/IDevicePolicyManager.aidl
index edb8603554ee0..a5508cd6b2f84 100644
--- a/core/java/android/app/IDevicePolicyManager.aidl
+++ b/core/java/android/app/IDevicePolicyManager.aidl
@@ -45,7 +45,8 @@ interface IDevicePolicyManager {
void wipeData(int flags);
void setActiveAdmin(in ComponentName policyReceiver);
- ComponentName getActiveAdmin();
+ boolean isAdminActive(in ComponentName policyReceiver);
+ List getActiveAdmins();
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result);
void removeActiveAdmin(in ComponentName policyReceiver);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index aafe453fd7a42..bd41a1352c508 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -121,11 +121,6 @@ public class LockPatternUtils {
}
- public boolean isDevicePolicyActive() {
- ComponentName admin = mDevicePolicyManager.getActiveAdmin();
- return admin != null ? mDevicePolicyManager.isAdminActive(admin) : false;
- }
-
public int getRequestedMinimumPasswordLength() {
return mDevicePolicyManager.getMinimumPasswordLength();
}
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index ebd6f3d0bac37..7b8645f7499d8 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -35,7 +35,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Binder;
-import android.os.Handler;
import android.os.IBinder;
import android.os.IPowerManager;
import android.os.RecoverySystem;
@@ -49,6 +48,8 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
/**
@@ -65,7 +66,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
int mActivePasswordLength = 0;
int mFailedPasswordAttempts = 0;
- ActiveAdmin mActiveAdmin;
+ final HashMap mAdminMap
+ = new HashMap();
+ final ArrayList mAdminList
+ = new ArrayList();
static class ActiveAdmin {
final DeviceAdminInfo info;
@@ -148,7 +152,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who) {
- ActiveAdmin admin = mActiveAdmin;
+ ActiveAdmin admin = mAdminMap.get(who);
if (admin != null
&& who.getPackageName().equals(admin.info.getActivityInfo().packageName)
&& who.getClassName().equals(admin.info.getActivityInfo().name)) {
@@ -159,7 +163,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
ActiveAdmin getActiveAdminForCallerLocked(ComponentName who)
throws SecurityException {
- ActiveAdmin admin = mActiveAdmin;
+ ActiveAdmin admin = mAdminMap.get(who);
if (admin != null && admin.getUid() == Binder.getCallingUid()) {
if (who != null) {
if (!who.getPackageName().equals(admin.info.getActivityInfo().packageName)
@@ -167,7 +171,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
throw new SecurityException("Current admin is not " + who);
}
}
- return mActiveAdmin;
+ return admin;
}
throw new SecurityException("Current admin is not owned by uid " + Binder.getCallingUid());
}
@@ -190,28 +194,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
void sendAdminCommandLocked(String action, int reqPolicy) {
- if (mActiveAdmin != null) {
- if (mActiveAdmin.info.usesPolicy(reqPolicy)) {
- return;
+ final int N = mAdminList.size();
+ if (N > 0) {
+ for (int i=0; i getActiveAdmins() {
+ synchronized (this) {
+ final int N = mAdminList.size();
+ if (N <= 0) {
+ return null;
+ }
+ ArrayList res = new ArrayList(N);
+ for (int i=0; i admin.maximumFailedPasswordsForWipe) {
+ count = admin.maximumFailedPasswordsForWipe;
+ }
+ }
+ return count;
}
}
@@ -546,7 +594,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
public long getMaximumTimeToLock() {
synchronized (this) {
- return mActiveAdmin != null ? mActiveAdmin.maximumTimeToUnlock : 0;
+ final int N = mAdminList.size();
+ long time = 0;
+ for (int i=0; i admin.maximumTimeToUnlock) {
+ time = admin.maximumTimeToUnlock;
+ }
+ }
+ return time;
}
}