Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab74309e authored by Francois Gaffie's avatar Francois Gaffie Committed by Christophe Koessler
Browse files

[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: default avatarFrancois Gaffie <francois.gaffie@renault.com>
Change-Id: Ia26467f27b31bc048bdb141beac7d764fcb27f51
parent ac32a364
Loading
Loading
Loading
Loading
+25 −20
Original line number Diff line number Diff line
@@ -33,6 +33,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;
@@ -73,7 +74,6 @@ import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.io.PrintWriter;
@@ -184,6 +184,8 @@ public class PreferencesHelper implements RankingConfig {

    private Map<String, List<String>> mOemLockedApps = new HashMap();

    private int mCurrentUserId = UserHandle.USER_NULL;

    public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
            ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
            AppOpsManager appOpsManager,
@@ -199,7 +201,8 @@ public class PreferencesHelper implements RankingConfig {
        updateBadgingEnabled();
        updateBubblesEnabled();
        updateMediaNotificationFilteringEnabled();
        syncChannelsBypassingDnd(mContext.getUserId());
        mCurrentUserId = ActivityManager.getCurrentUser();
        syncChannelsBypassingDnd();
    }

    public void readXml(TypedXmlPullParser parser, boolean forRestore, int userId)
@@ -806,7 +809,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();
                    }
                }
            }
@@ -888,13 +891,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();
                        }
                    }
                }
@@ -958,7 +961,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));
@@ -1047,7 +1050,7 @@ public class PreferencesHelper implements RankingConfig {

            if (updatedChannel.canBypassDnd() != mAreChannelsBypassingDnd
                    || channel.getImportance() != updatedChannel.getImportance()) {
                updateChannelsBypassingDnd(mContext.getUserId());
                updateChannelsBypassingDnd();
            }
        }
        updateConfig();
@@ -1145,7 +1148,7 @@ public class PreferencesHelper implements RankingConfig {
            mNotificationChannelLogger.logNotificationChannelDeleted(channel, uid, pkg);

            if (mAreChannelsBypassingDnd && channel.canBypassDnd()) {
                updateChannelsBypassingDnd(mContext.getUserId());
                updateChannelsBypassingDnd();
            }
        }
    }
@@ -1512,7 +1515,7 @@ public class PreferencesHelper implements RankingConfig {
                }
            }
            if (!deletedChannelIds.isEmpty() && mAreChannelsBypassingDnd) {
                updateChannelsBypassingDnd(mContext.getUserId());
                updateChannelsBypassingDnd();
            }
            return deletedChannelIds;
        }
@@ -1658,29 +1661,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;
                }

@@ -2226,14 +2229,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) {