Allowing profile to set a subset of keyguard restrictions.
Allow admins in managed profiles disable trust related
keyguard features (trust agents and finger prints) for the
parent user.
Allow admins in managed profiles to control whether notifications
from the profile are redacted on the keyguard.
Bug: 18581512
Change-Id: Ic2323671f63781630206cc2efcc8e27ee58c38e6
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ae07206..d7e613c 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2523,13 +2523,26 @@
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
* this method; if it has not, a security exception will be thrown.
*
- * <p>Calling this from a managed profile will throw a security exception.
+ * <p>Calling this from a managed profile before version
+ * {@link android.os.Build.VERSION_CODES#MNC} will throw a security exception.
+ *
+ * <p>From version {@link android.os.Build.VERSION_CODES#MNC} a profile owner can set:
+ * <ul>
+ * <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, {@link #KEYGUARD_DISABLE_FINGERPRINT}
+ * these will affect the profile's parent user.
+ * <li>{@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS} this will affect notifications
+ * generated by applications in the managed profile.
+ * </ul>
+ * <p>Requests to disable other features on a managed profile will be ignored. The admin
+ * can check which features have been disabled by calling
+ * {@link #getKeyguardDisabledFeatures(ComponentName)}
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default),
* {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA},
* {@link #KEYGUARD_DISABLE_SECURE_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_TRUST_AGENTS},
- * {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FEATURES_ALL}
+ * {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FINGERPRINT},
+ * {@link #KEYGUARD_DISABLE_FEATURES_ALL}
*/
public void setKeyguardDisabledFeatures(ComponentName admin, int which) {
if (mService != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 588ec26..2913c7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -395,11 +395,6 @@
Toast.LENGTH_SHORT).show();
}
}
- } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
- action)) {
- mUsersAllowingPrivateNotifications.clear();
- updateLockscreenNotificationSetting();
- updateNotifications();
} else if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
NotificationManager noMan = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -419,6 +414,19 @@
}
};
+ private final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) &&
+ isCurrentProfile(getSendingUserId())) {
+ mUsersAllowingPrivateNotifications.clear();
+ updateLockscreenNotificationSetting();
+ updateNotifications();
+ }
+ }
+ };
+
private final NotificationListenerService mNotificationListener =
new NotificationListenerService() {
@Override
@@ -631,9 +639,13 @@
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(BANNER_ACTION_CANCEL);
filter.addAction(BANNER_ACTION_SETUP);
- filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
+ IntentFilter allUsersFilter = new IntentFilter();
+ allUsersFilter.addAction(
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter,
+ null, null);
updateCurrentProfilesCache();
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 67c198f..43e6f76 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -245,6 +245,17 @@
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
}
+ // Keyguard features that when set of a profile will affect the profiles
+ // parent user.
+ private static final int PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER =
+ DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS
+ | DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
+
+ // Keyguard features that are allowed to be set on a managed profile
+ private static final int PROFILE_KEYGUARD_FEATURES =
+ PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER
+ | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
final Context mContext;
final UserManager mUserManager;
final PowerManager.WakeLock mWakeLock;
@@ -3956,7 +3967,9 @@
}
Preconditions.checkNotNull(who, "ComponentName is null");
final int userHandle = UserHandle.getCallingUserId();
- enforceNotManagedProfile(userHandle, "disable keyguard features");
+ if (isManagedProfile(userHandle)) {
+ which = which & PROFILE_KEYGUARD_FEATURES;
+ }
synchronized (this) {
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
@@ -3977,21 +3990,50 @@
return 0;
}
enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return (admin != null) ? admin.disabledKeyguardFeatures : 0;
- }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ if (who != null) {
+ ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+ return (admin != null) ? admin.disabledKeyguardFeatures : 0;
+ }
- // Determine which keyguard features are disabled for any active admins.
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- int which = 0;
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- which |= admin.disabledKeyguardFeatures;
+ UserInfo user = mUserManager.getUserInfo(userHandle);
+ final List<UserInfo> profiles;
+ if (user.isManagedProfile()) {
+ // If we are being asked about a managed profile just return
+ // keyguard features disabled by admins in the profile.
+ profiles = new ArrayList<UserInfo>(1);
+ profiles.add(user);
+ } else {
+ // Otherwise return those set by admins in the user
+ // and its profiles.
+ profiles = mUserManager.getProfiles(userHandle);
+ }
+
+ // Determine which keyguard features are disabled by any active admin.
+ int which = 0;
+ for (UserInfo userInfo : profiles) {
+ DevicePolicyData policy = getUserData(userInfo.id);
+ final int N = policy.mAdminList.size();
+ for (int i = 0; i < N; i++) {
+ ActiveAdmin admin = policy.mAdminList.get(i);
+ if (userInfo.id == userHandle || !userInfo.isManagedProfile()) {
+ // If we are being asked explictly about this user
+ // return all disabled features even if its a managed profile.
+ which |= admin.disabledKeyguardFeatures;
+ } else {
+ // Otherwise a managed profile is only allowed to disable
+ // some features on the parent user.
+ which |= (admin.disabledKeyguardFeatures
+ & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER);
+ }
+ }
+ }
+ return which;
}
- return which;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}