From 92a9f5fc1d07d5ab8b89b02d09b73f355595449c Mon Sep 17 00:00:00 2001 From: Francois Gaffie Date: Wed, 24 Feb 2021 17:26:29 +0100 Subject: [PATCH] [Notification] Fix Notification channel Dnd bypass for multiusers -Permission granted for a given package using shell cmd (user system) are not sufficient due to a check of notification uid vs packagepreference uid. -If the packagepreference is deleted then restored, the channel preference are not taken into account. Bug: 178032672 Test: CTS/AudioManagerTest Signed-off-by: Francois Gaffie Change-Id: Ia26467f27b31bc048bdb141beac7d764fcb27f51 Merged-in: Ia26467f27b31bc048bdb141beac7d764fcb27f51 --- .../notification/PreferencesHelper.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index 7d1827d1b6e2d..0c1ba962323fc 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -32,6 +32,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityManager; import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationChannel; @@ -177,6 +178,8 @@ public class PreferencesHelper implements RankingConfig { private Map> mOemLockedApps = new HashMap(); + private int mCurrentUserId = UserHandle.USER_NULL; + public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler, ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger, AppOpsManager appOpsManager, @@ -191,7 +194,8 @@ public class PreferencesHelper implements RankingConfig { updateBadgingEnabled(); updateBubblesEnabled(); - syncChannelsBypassingDnd(mContext.getUserId()); + mCurrentUserId = ActivityManager.getCurrentUser(); + syncChannelsBypassingDnd(); } public void readXml(XmlPullParser parser, boolean forRestore, int userId) @@ -790,7 +794,7 @@ public class PreferencesHelper implements RankingConfig { // but the system can if (group.isBlocked() != oldGroup.isBlocked()) { group.lockFields(NotificationChannelGroup.USER_LOCKED_BLOCKED_STATE); - updateChannelsBypassingDnd(mContext.getUserId()); + updateChannelsBypassingDnd(); } } } @@ -871,13 +875,13 @@ public class PreferencesHelper implements RankingConfig { // fields on the channel yet if (existing.getUserLockedFields() == 0 && hasDndAccess) { boolean bypassDnd = channel.canBypassDnd(); - if (bypassDnd != existing.canBypassDnd()) { + if (bypassDnd != existing.canBypassDnd() || wasUndeleted) { existing.setBypassDnd(bypassDnd); needsPolicyFileChange = true; if (bypassDnd != mAreChannelsBypassingDnd || previousExistingImportance != existing.getImportance()) { - updateChannelsBypassingDnd(mContext.getUserId()); + updateChannelsBypassingDnd(); } } } @@ -941,7 +945,7 @@ public class PreferencesHelper implements RankingConfig { r.channels.put(channel.getId(), channel); if (channel.canBypassDnd() != mAreChannelsBypassingDnd) { - updateChannelsBypassingDnd(mContext.getUserId()); + updateChannelsBypassingDnd(); } MetricsLogger.action(getChannelLog(channel, pkg).setType( com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN)); @@ -1013,7 +1017,7 @@ public class PreferencesHelper implements RankingConfig { if (updatedChannel.canBypassDnd() != mAreChannelsBypassingDnd || channel.getImportance() != updatedChannel.getImportance()) { - updateChannelsBypassingDnd(mContext.getUserId()); + updateChannelsBypassingDnd(); } } updateConfig(); @@ -1110,7 +1114,7 @@ public class PreferencesHelper implements RankingConfig { mNotificationChannelLogger.logNotificationChannelDeleted(channel, uid, pkg); if (mAreChannelsBypassingDnd && channel.canBypassDnd()) { - updateChannelsBypassingDnd(mContext.getUserId()); + updateChannelsBypassingDnd(); } } } @@ -1454,7 +1458,7 @@ public class PreferencesHelper implements RankingConfig { } } if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) { - updateChannelsBypassingDnd(mContext.getUserId()); + updateChannelsBypassingDnd(); } return deletedChannelIds; } @@ -1600,29 +1604,29 @@ public class PreferencesHelper implements RankingConfig { } /** - * Syncs {@link #mAreChannelsBypassingDnd} with the user's notification policy before + * Syncs {@link #mAreChannelsBypassingDnd} with the current user's notification policy before * updating - * @param userId */ - private void syncChannelsBypassingDnd(int userId) { + private void syncChannelsBypassingDnd() { mAreChannelsBypassingDnd = (mZenModeHelper.getNotificationPolicy().state & NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND) == 1; - updateChannelsBypassingDnd(userId); + updateChannelsBypassingDnd(); } /** - * Updates the user's NotificationPolicy based on whether the given userId + * Updates the user's NotificationPolicy based on whether the current userId * has channels bypassing DND * @param userId */ - private void updateChannelsBypassingDnd(int userId) { + private void updateChannelsBypassingDnd() { synchronized (mPackagePreferences) { final int numPackagePreferences = mPackagePreferences.size(); for (int i = 0; i < numPackagePreferences; i++) { final PackagePreferences r = mPackagePreferences.valueAt(i); - // Package isn't associated with this userId or notifications from this package are - // blocked - if (userId != UserHandle.getUserId(r.uid) || r.importance == IMPORTANCE_NONE) { + // Package isn't associated with the current userId or notifications from this + // package are blocked + if (mCurrentUserId != UserHandle.getUserId(r.uid) + || r.importance == IMPORTANCE_NONE) { continue; } @@ -2168,14 +2172,16 @@ public class PreferencesHelper implements RankingConfig { * Called when user switches */ public void onUserSwitched(int userId) { - syncChannelsBypassingDnd(userId); + mCurrentUserId = userId; + syncChannelsBypassingDnd(); } /** * Called when user is unlocked */ public void onUserUnlocked(int userId) { - syncChannelsBypassingDnd(userId); + mCurrentUserId = userId; + syncChannelsBypassingDnd(); } public void onUserRemoved(int userId) {