From d47c6ed4a9f2b5bd31f6c806b74701428efe458b Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 27 Jan 2010 16:21:20 -0800 Subject: [PATCH] Bite the bullet and add support for multiple device admins. --- api/current.xml | 11 ++ core/java/android/app/Activity.java | 2 +- .../java/android/app/DevicePolicyManager.java | 44 +++--- .../android/app/IDevicePolicyManager.aidl | 3 +- .../internal/widget/LockPatternUtils.java | 5 - .../server/DevicePolicyManagerService.java | 145 ++++++++++++------ 6 files changed, 135 insertions(+), 75 deletions(-) diff --git a/api/current.xml b/api/current.xml index a32c7576b82a7..d79b5cca183f4 100644 --- a/api/current.xml +++ b/api/current.xml @@ -20399,6 +20399,17 @@ deprecated="not deprecated" visibility="public" > + + 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; } }