Make UserManager enforce user restrictions, not DPM.
- Now even if a user restriction is set via UserManager, it'll be correctly
enforced.
- Changed the way AudioService enforces the OP_MUTE_MICROPHONE and
OP_AUDIO_MASTER_VOLUME app ops -- previously, when they're set, even a muting
call would be rejected. This was why DPMS.setUserRestriction() used different
calling orders for DISALLOW_UNMUTE_MICROPHONE/DISALLOW_ADJUST_VOLUME depending
on setting them or clearing them.
Now, even when the app ops are set, we still allow muting calls.
Bug 23902097
Bug 24981972
Change-Id: I865b5de43e15f5955f94006475a5ec6254904d31
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index c1f827f..62ced52 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -199,6 +199,14 @@
@GuardedBy("mRestrictionsLock")
private final SparseArray<Bundle> mCachedEffectiveUserRestrictions = new SparseArray<>();
+ /**
+ * User restrictions that have already been applied in {@link #applyUserRestrictionsRL}. We
+ * use it to detect restrictions that have changed since the last
+ * {@link #applyUserRestrictionsRL} call.
+ */
+ @GuardedBy("mRestrictionsLock")
+ private final SparseArray<Bundle> mAppliedUserRestrictions = new SparseArray<>();
+
private final Bundle mGuestRestrictions = new Bundle();
/**
@@ -727,8 +735,6 @@
Log.d(LOG_TAG, "updateUserRestrictionsInternalLocked userId=" + userId
+ " bundle=" + newRestrictions);
}
- final Bundle prevRestrictions = getEffectiveUserRestrictions(userId);
-
// Update system restrictions.
if (newRestrictions != null) {
// If newRestrictions == the current one, it's probably a bug.
@@ -742,12 +748,18 @@
mCachedEffectiveUserRestrictions.put(userId, effective);
- applyUserRestrictionsRL(userId, effective, prevRestrictions);
+ applyUserRestrictionsRL(userId, effective);
}
@GuardedBy("mRestrictionsLock")
- private void applyUserRestrictionsRL(int userId,
- Bundle newRestrictions, Bundle prevRestrictions) {
+ private void applyUserRestrictionsRL(int userId, Bundle newRestrictions) {
+ final Bundle prevRestrictions = mAppliedUserRestrictions.get(userId);
+
+ if (DBG) {
+ Log.d(LOG_TAG, "applyUserRestrictionsRL userId=" + userId
+ + " new=" + newRestrictions + " prev=" + prevRestrictions);
+ }
+
final long token = Binder.clearCallingIdentity();
try {
mAppOpsService.setUserRestrictions(newRestrictions, userId);
@@ -757,7 +769,10 @@
Binder.restoreCallingIdentity(token);
}
- // TODO Move the code from DPMS.setUserRestriction().
+ UserRestrictionsUtils.applyUserRestrictions(
+ mContext, userId, newRestrictions, prevRestrictions);
+
+ mAppliedUserRestrictions.put(userId, new Bundle(newRestrictions));
}
@GuardedBy("mRestrictionsLock")
@@ -768,9 +783,8 @@
@GuardedBy("mRestrictionsLock")
private void updateEffectiveUserRestrictionsForAllUsersRL() {
// First, invalidate all cached values.
- synchronized (mRestrictionsLock) {
- mCachedEffectiveUserRestrictions.clear();
- }
+ mCachedEffectiveUserRestrictions.clear();
+
// We don't want to call into ActivityManagerNative while taking a lock, so we'll call
// it on a handler.
final Runnable r = new Runnable() {