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

Commit 413ba846 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Don't allow importance updates for oem locked channels

Test: atest, make sure missed call notifications are no
longer demoted by aosp notification assistant
Change-Id: I80728bae67501d64359e0dac02dca928c34a7e95
Fixes: 122657004
parent 5ca575ae
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -219,6 +219,11 @@ package android.app {
    method public abstract void onOpActiveChanged(int, int, java.lang.String, boolean);
  }

  public final class NotificationChannel implements android.os.Parcelable {
    method public boolean isImportanceLockedByOEM();
    method public void setImportanceLockedByOEM(boolean);
  }

  public final class NotificationChannelGroup implements android.os.Parcelable {
    method public int getUserLockedFields();
    method public void lockFields(int);
+44 −20
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH;

import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.NotificationManager.Importance;
import android.content.ContentResolver;
@@ -168,6 +169,7 @@ public final class NotificationChannel implements Parcelable {
    // If this is a blockable system notification channel.
    private boolean mBlockableSystem = false;
    private boolean mAllowAppOverlay = DEFAULT_ALLOW_APP_OVERLAY;
    private boolean mImportanceLockedByOEM;

    /**
     * Creates a notification channel.
@@ -230,6 +232,7 @@ public final class NotificationChannel implements Parcelable {
        mLightColor = in.readInt();
        mBlockableSystem = in.readBoolean();
        mAllowAppOverlay = in.readBoolean();
        mImportanceLockedByOEM = in.readBoolean();
    }

    @Override
@@ -283,6 +286,7 @@ public final class NotificationChannel implements Parcelable {
        dest.writeInt(mLightColor);
        dest.writeBoolean(mBlockableSystem);
        dest.writeBoolean(mAllowAppOverlay);
        dest.writeBoolean(mImportanceLockedByOEM);
    }

    /**
@@ -648,6 +652,22 @@ public final class NotificationChannel implements Parcelable {
        return mBlockableSystem;
    }

    /**
     * @hide
     */
    @TestApi
    public void setImportanceLockedByOEM(boolean locked) {
        mImportanceLockedByOEM = locked;
    }

    /**
     * @hide
     */
    @TestApi
    public boolean isImportanceLockedByOEM() {
        return mImportanceLockedByOEM;
    }

    /**
     * Returns whether the user has chosen the importance of this channel, either to affirm the
     * initial selection from the app, or changed it to be higher or lower.
@@ -952,25 +972,26 @@ public final class NotificationChannel implements Parcelable {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        NotificationChannel that = (NotificationChannel) o;
        return getImportance() == that.getImportance() &&
                mBypassDnd == that.mBypassDnd &&
                getLockscreenVisibility() == that.getLockscreenVisibility() &&
                mLights == that.mLights &&
                getLightColor() == that.getLightColor() &&
                getUserLockedFields() == that.getUserLockedFields() &&
                isFgServiceShown() == that.isFgServiceShown() &&
                mVibrationEnabled == that.mVibrationEnabled &&
                mShowBadge == that.mShowBadge &&
                isDeleted() == that.isDeleted() &&
                isBlockableSystem() == that.isBlockableSystem() &&
                mAllowAppOverlay == that.mAllowAppOverlay &&
                Objects.equals(getId(), that.getId()) &&
                Objects.equals(getName(), that.getName()) &&
                Objects.equals(mDesc, that.mDesc) &&
                Objects.equals(getSound(), that.getSound()) &&
                Arrays.equals(mVibration, that.mVibration) &&
                Objects.equals(getGroup(), that.getGroup()) &&
                Objects.equals(getAudioAttributes(), that.getAudioAttributes());
        return getImportance() == that.getImportance()
                && mBypassDnd == that.mBypassDnd
                && getLockscreenVisibility() == that.getLockscreenVisibility()
                && mLights == that.mLights
                && getLightColor() == that.getLightColor()
                && getUserLockedFields() == that.getUserLockedFields()
                && isFgServiceShown() == that.isFgServiceShown()
                && mVibrationEnabled == that.mVibrationEnabled
                && mShowBadge == that.mShowBadge
                && isDeleted() == that.isDeleted()
                && isBlockableSystem() == that.isBlockableSystem()
                && mAllowAppOverlay == that.mAllowAppOverlay
                && Objects.equals(getId(), that.getId())
                && Objects.equals(getName(), that.getName())
                && Objects.equals(mDesc, that.mDesc)
                && Objects.equals(getSound(), that.getSound())
                && Arrays.equals(mVibration, that.mVibration)
                && Objects.equals(getGroup(), that.getGroup())
                && Objects.equals(getAudioAttributes(), that.getAudioAttributes())
                && mImportanceLockedByOEM == that.mImportanceLockedByOEM;
    }

    @Override
@@ -979,7 +1000,8 @@ public final class NotificationChannel implements Parcelable {
                getLockscreenVisibility(), getSound(), mLights, getLightColor(),
                getUserLockedFields(),
                isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
                getAudioAttributes(), isBlockableSystem(), mAllowAppOverlay);
                getAudioAttributes(), isBlockableSystem(), mAllowAppOverlay,
                mImportanceLockedByOEM);
        result = 31 * result + Arrays.hashCode(mVibration);
        return result;
    }
@@ -1007,6 +1029,7 @@ public final class NotificationChannel implements Parcelable {
                + ", mAudioAttributes=" + mAudioAttributes
                + ", mBlockableSystem=" + mBlockableSystem
                + ", mAllowAppOverlay=" + mAllowAppOverlay
                + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
                + '}';
        pw.println(prefix + output);
    }
@@ -1033,6 +1056,7 @@ public final class NotificationChannel implements Parcelable {
                + ", mAudioAttributes=" + mAudioAttributes
                + ", mBlockableSystem=" + mBlockableSystem
                + ", mAllowAppOverlay=" + mAllowAppOverlay
                + ", mImportanceLockedByOEM=" + mImportanceLockedByOEM
                + '}';
    }

+3 −0
Original line number Diff line number Diff line
@@ -1581,6 +1581,9 @@ public class NotificationManagerService extends SystemService {

        mIsAutomotive =
                mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);

        mPreferencesHelper.lockChannelsForOEM(getContext().getResources().getStringArray(
                com.android.internal.R.array.config_nonBlockableNotificationPackages));
    }

    @Override
+2 −1
Original line number Diff line number Diff line
@@ -785,7 +785,8 @@ public final class NotificationRecord {
            mImportanceExplanation = "user";
        }
        if (!getChannel().hasUserSetImportance()
                && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
                && mAssistantImportance != IMPORTANCE_UNSPECIFIED
                && !getChannel().isImportanceLockedByOEM()) {
            mImportance = mAssistantImportance;
            mImportanceExplanation = "asst";
        }
+54 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ public class PreferencesHelper implements RankingConfig {
    private static final String TAG = "NotificationPrefHelper";
    private static final int XML_VERSION = 1;
    private static final int UNKNOWN_UID = UserHandle.USER_NULL;
    private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";

    @VisibleForTesting
    static final String TAG_RANKING = "ranking";
@@ -94,6 +95,7 @@ public class PreferencesHelper implements RankingConfig {
    private static final int DEFAULT_IMPORTANCE = NotificationManager.IMPORTANCE_UNSPECIFIED;
    private static final boolean DEFAULT_SHOW_BADGE = true;
    private static final boolean DEFAULT_ALLOW_APP_OVERLAY = true;
    private static final boolean DEFAULT_OEM_LOCKED_IMPORTANCE  = false;
    /**
     * Default value for what fields are user locked. See {@link LockableAppFields} for all lockable
     * fields.
@@ -621,6 +623,12 @@ public class PreferencesHelper implements RankingConfig {
            channel.setLockscreenVisibility(r.visibility);
        }
        clearLockedFields(channel);
        channel.setImportanceLockedByOEM(r.oemLockedImportance);
        if (!channel.isImportanceLockedByOEM()) {
            if (r.futureOemLockedChannels.remove(channel.getId())) {
                channel.setImportanceLockedByOEM(true);
            }
        }
        if (channel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
            channel.setLockscreenVisibility(
                    NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
@@ -664,6 +672,12 @@ public class PreferencesHelper implements RankingConfig {
        } else {
            updatedChannel.unlockFields(updatedChannel.getUserLockedFields());
        }
        // no importance updates are allowed if OEM blocked it
        updatedChannel.setImportanceLockedByOEM(channel.isImportanceLockedByOEM());
        if (updatedChannel.isImportanceLockedByOEM()) {
            updatedChannel.setImportance(channel.getImportance());
        }

        r.channels.put(updatedChannel.getId(), updatedChannel);

        if (onlyHasDefaultChannel(pkg, uid)) {
@@ -753,6 +767,44 @@ public class PreferencesHelper implements RankingConfig {
        }
    }

    public void lockChannelsForOEM(String[] appOrChannelList) {
        if (appOrChannelList == null) {
            return;
        }
        for (String appOrChannel : appOrChannelList) {
            if (!TextUtils.isEmpty(appOrChannel)) {
                String[] appSplit = appOrChannel.split(NON_BLOCKABLE_CHANNEL_DELIM);
                if (appSplit != null && appSplit.length > 0) {
                    String appName = appSplit[0];
                    String channelId = appSplit.length == 2 ? appSplit[1] : null;

                    synchronized (mPackagePreferences) {
                        for (PackagePreferences r : mPackagePreferences.values()) {
                            if (r.pkg.equals(appName)) {
                                if (channelId == null) {
                                    // lock all channels for the app
                                    r.oemLockedImportance = true;
                                    for (NotificationChannel channel : r.channels.values()) {
                                        channel.setImportanceLockedByOEM(true);
                                    }
                                } else {
                                    NotificationChannel channel = r.channels.get(channelId);
                                    if (channel != null) {
                                        channel.setImportanceLockedByOEM(true);
                                    } else {
                                        // if this channel shows up in the future, make sure it'll
                                        // be locked immediately
                                        r.futureOemLockedChannels.add(channelId);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public NotificationChannelGroup getNotificationChannelGroupWithChannels(String pkg,
            int uid, String groupId, boolean includeDeleted) {
        Preconditions.checkNotNull(pkg);
@@ -1604,6 +1656,8 @@ public class PreferencesHelper implements RankingConfig {
        boolean showBadge = DEFAULT_SHOW_BADGE;
        boolean appOverlay = DEFAULT_ALLOW_APP_OVERLAY;
        int lockedAppFields = DEFAULT_LOCKED_APP_FIELDS;
        boolean oemLockedImportance = DEFAULT_OEM_LOCKED_IMPORTANCE;
        List<String> futureOemLockedChannels = new ArrayList<>();

        Delegate delegate = null;
        ArrayMap<String, NotificationChannel> channels = new ArrayMap<>();
Loading