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

Commit 24edc003 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Separate concept of VIC from DND

(Very important conversations). Track VICs in a different
field, and update DND (and public apis) to allow
all, important, or no conversations through.

Test: atest, cts
Bug: 137397357

Change-Id: Iae04546eb7c0b1e79cfdbeec7311628cd7ad634a
parent df245727
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -5918,6 +5918,7 @@ package android.app {
    method public long[] getVibrationPattern();
    method public boolean hasUserSetImportance();
    method public boolean hasUserSetSound();
    method public boolean isImportantConversation();
    method public void setAllowBubbles(boolean);
    method public void setBypassDnd(boolean);
    method public void setConversationId(@Nullable String, @Nullable String);
@@ -6030,14 +6031,19 @@ package android.app {
  public static class NotificationManager.Policy implements android.os.Parcelable {
    ctor public NotificationManager.Policy(int, int, int);
    ctor public NotificationManager.Policy(int, int, int, int);
    ctor public NotificationManager.Policy(int, int, int, int, int);
    method public int describeContents();
    method public static String priorityCategoriesToString(int);
    method public static String prioritySendersToString(int);
    method public static String suppressedEffectsToString(int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final int CONVERSATION_SENDERS_ANYONE = 1; // 0x1
    field public static final int CONVERSATION_SENDERS_IMPORTANT = 2; // 0x2
    field public static final int CONVERSATION_SENDERS_NONE = 3; // 0x3
    field @NonNull public static final android.os.Parcelable.Creator<android.app.NotificationManager.Policy> CREATOR;
    field public static final int PRIORITY_CATEGORY_ALARMS = 32; // 0x20
    field public static final int PRIORITY_CATEGORY_CALLS = 8; // 0x8
    field public static final int PRIORITY_CATEGORY_CONVERSATIONS = 256; // 0x100
    field public static final int PRIORITY_CATEGORY_EVENTS = 2; // 0x2
    field public static final int PRIORITY_CATEGORY_MEDIA = 64; // 0x40
    field public static final int PRIORITY_CATEGORY_MESSAGES = 4; // 0x4
@@ -6058,6 +6064,7 @@ package android.app {
    field public static final int SUPPRESSED_EFFECT_STATUS_BAR = 32; // 0x20
    field public final int priorityCallSenders;
    field public final int priorityCategories;
    field public final int priorityConversationSenders;
    field public final int priorityMessageSenders;
    field public final int suppressedVisualEffects;
  }
@@ -43775,12 +43782,14 @@ package android.service.notification {
    method public int getPriorityCallSenders();
    method public int getPriorityCategoryAlarms();
    method public int getPriorityCategoryCalls();
    method public int getPriorityCategoryConversations();
    method public int getPriorityCategoryEvents();
    method public int getPriorityCategoryMedia();
    method public int getPriorityCategoryMessages();
    method public int getPriorityCategoryReminders();
    method public int getPriorityCategoryRepeatCallers();
    method public int getPriorityCategorySystem();
    method public int getPriorityConversationSenders();
    method public int getPriorityMessageSenders();
    method public int getVisualEffectAmbient();
    method public int getVisualEffectBadge();
@@ -43790,6 +43799,10 @@ package android.service.notification {
    method public int getVisualEffectPeek();
    method public int getVisualEffectStatusBar();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final int CONVERSATION_SENDERS_ANYONE = 1; // 0x1
    field public static final int CONVERSATION_SENDERS_IMPORTANT = 2; // 0x2
    field public static final int CONVERSATION_SENDERS_NONE = 3; // 0x3
    field public static final int CONVERSATION_SENDERS_UNSET = 0; // 0x0
    field @NonNull public static final android.os.Parcelable.Creator<android.service.notification.ZenPolicy> CREATOR;
    field public static final int PEOPLE_TYPE_ANYONE = 1; // 0x1
    field public static final int PEOPLE_TYPE_CONTACTS = 2; // 0x2
@@ -43806,6 +43819,7 @@ package android.service.notification {
    method @NonNull public android.service.notification.ZenPolicy.Builder allowAlarms(boolean);
    method @NonNull public android.service.notification.ZenPolicy.Builder allowAllSounds();
    method @NonNull public android.service.notification.ZenPolicy.Builder allowCalls(int);
    method @NonNull public android.service.notification.ZenPolicy.Builder allowConversations(int);
    method @NonNull public android.service.notification.ZenPolicy.Builder allowEvents(boolean);
    method @NonNull public android.service.notification.ZenPolicy.Builder allowMedia(boolean);
    method @NonNull public android.service.notification.ZenPolicy.Builder allowMessages(int);
+1 −0
Original line number Diff line number Diff line
@@ -416,6 +416,7 @@ package android.app {
    method public void setFgServiceShown(boolean);
    method public void setImportanceLockedByCriticalDeviceFunction(boolean);
    method public void setImportanceLockedByOEM(boolean);
    method public void setImportantConversation(boolean);
    method public void setOriginalImportance(int);
  }

+33 −4
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.os.Parcelable;
import android.provider.Settings;
import android.service.notification.NotificationListenerService;
import android.text.TextUtils;
import android.util.Log;
import android.util.proto.ProtoOutputStream;

import com.android.internal.util.Preconditions;
@@ -105,6 +104,7 @@ public final class NotificationChannel implements Parcelable {
    private static final String ATT_ORIG_IMP = "orig_imp";
    private static final String ATT_PARENT_CHANNEL = "parent";
    private static final String ATT_CONVERSATION_ID = "conv_id";
    private static final String ATT_IMP_CONVERSATION = "imp_conv";
    private static final String ATT_DEMOTE = "dem";
    private static final String DELIMITER = ",";

@@ -196,6 +196,7 @@ public final class NotificationChannel implements Parcelable {
    private String mParentId = null;
    private String mConversationId = null;
    private boolean mDemoted = false;
    private boolean mImportantConvo = false;

    /**
     * Creates a notification channel.
@@ -263,6 +264,7 @@ public final class NotificationChannel implements Parcelable {
        mParentId = in.readString();
        mConversationId = in.readString();
        mDemoted = in.readBoolean();
        mImportantConvo = in.readBoolean();
    }

    @Override
@@ -321,6 +323,7 @@ public final class NotificationChannel implements Parcelable {
        dest.writeString(mParentId);
        dest.writeString(mConversationId);
        dest.writeBoolean(mDemoted);
        dest.writeBoolean(mImportantConvo);
    }

    /**
@@ -353,6 +356,14 @@ public final class NotificationChannel implements Parcelable {
        mDeleted = deleted;
    }

    /**
     * @hide
     */
    @TestApi
    public void setImportantConversation(boolean importantConvo) {
        mImportantConvo = importantConvo;
    }

    /**
     * Allows users to block notifications sent through this channel, if this channel belongs to
     * a package that is signed with the system signature. If the channel does not belong to a
@@ -600,6 +611,18 @@ public final class NotificationChannel implements Parcelable {
        return mBypassDnd;
    }

    /**
     * Whether or not notifications in this conversation are considered important.
     *
     * <p>Important conversations may get special visual treatment, and might be able to bypass DND.
     *
     * <p>This is only valid for channels that represent conversations, that is, those with a valid
     * {@link #getConversationId() conversation id}.
     */
    public boolean isImportantConversation() {
        return mImportantConvo;
    }

    /**
     * Returns the notification sound for this channel.
     */
@@ -852,6 +875,7 @@ public final class NotificationChannel implements Parcelable {
        setConversationId(parser.getAttributeValue(null, ATT_PARENT_CHANNEL),
                parser.getAttributeValue(null, ATT_CONVERSATION_ID));
        setDemoted(safeBool(parser, ATT_DEMOTE, false));
        setImportantConversation(safeBool(parser, ATT_IMP_CONVERSATION, false));
    }

    @Nullable
@@ -985,6 +1009,9 @@ public final class NotificationChannel implements Parcelable {
        if (isDemoted()) {
            out.attribute(null, ATT_DEMOTE, Boolean.toString(isDemoted()));
        }
        if (isImportantConversation()) {
            out.attribute(null, ATT_IMP_CONVERSATION, Boolean.toString(isImportantConversation()));
        }

        // mImportanceLockedDefaultApp and mImportanceLockedByOEM have a different source of
        // truth and so aren't written to this xml file
@@ -1145,7 +1172,8 @@ public final class NotificationChannel implements Parcelable {
                && mOriginalImportance == that.mOriginalImportance
                && Objects.equals(getParentChannelId(), that.getParentChannelId())
                && Objects.equals(getConversationId(), that.getConversationId())
                && isDemoted() == that.isDemoted();
                && isDemoted() == that.isDemoted()
                && isImportantConversation() == that.isImportantConversation();
    }

    @Override
@@ -1156,7 +1184,7 @@ public final class NotificationChannel implements Parcelable {
                isFgServiceShown(), mVibrationEnabled, mShowBadge, isDeleted(), getGroup(),
                getAudioAttributes(), isBlockableSystem(), mAllowBubbles,
                mImportanceLockedByOEM, mImportanceLockedDefaultApp, mOriginalImportance,
                mParentId, mConversationId, mDemoted);
                mParentId, mConversationId, mDemoted, mImportantConvo);
        result = 31 * result + Arrays.hashCode(mVibration);
        return result;
    }
@@ -1204,7 +1232,8 @@ public final class NotificationChannel implements Parcelable {
                + ", mOriginalImp=" + mOriginalImportance
                + ", mParent=" + mParentId
                + ", mConversationId=" + mConversationId
                + ", mDemoted=" + mDemoted;
                + ", mDemoted=" + mDemoted
                + ", mImportantConvo=" + mImportantConvo;
    }

    /** @hide */
+137 −36
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.service.notification.Adjustment;
import android.service.notification.Condition;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenPolicy;
import android.util.Log;
import android.util.proto.ProtoOutputStream;

@@ -1555,6 +1556,10 @@ public class NotificationManager {
        public static final int PRIORITY_CATEGORY_MEDIA = 1 << 6;
        /**System (catch-all for non-never suppressible sounds) are prioritized */
        public static final int PRIORITY_CATEGORY_SYSTEM = 1 << 7;
        /**
         * Conversations are allowed through DND.
         */
        public static final int PRIORITY_CATEGORY_CONVERSATIONS = 1 << 8;

        /**
         * @hide
@@ -1568,6 +1573,7 @@ public class NotificationManager {
                PRIORITY_CATEGORY_MESSAGES,
                PRIORITY_CATEGORY_CALLS,
                PRIORITY_CATEGORY_REPEAT_CALLERS,
                PRIORITY_CATEGORY_CONVERSATIONS,
        };

        /** Any sender is prioritized. */
@@ -1577,6 +1583,31 @@ public class NotificationManager {
        /** Only starred contacts are prioritized. */
        public static final int PRIORITY_SENDERS_STARRED = 2;


        /** @hide */
        @IntDef(prefix = { "CONVERSATION_SENDERS_" }, value = {
                CONVERSATION_SENDERS_ANYONE,
                CONVERSATION_SENDERS_IMPORTANT,
                CONVERSATION_SENDERS_NONE,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface ConversationSenders {}
        /**
         * Used to indicate all conversations can bypass dnd.
         */
        public static final int CONVERSATION_SENDERS_ANYONE = ZenPolicy.CONVERSATION_SENDERS_ANYONE;

        /**
         * Used to indicate important conversations can bypass dnd.
         */
        public static final int CONVERSATION_SENDERS_IMPORTANT =
                ZenPolicy.CONVERSATION_SENDERS_IMPORTANT;

        /**
         * Used to indicate no conversations can bypass dnd.
         */
        public static final int CONVERSATION_SENDERS_NONE = ZenPolicy.CONVERSATION_SENDERS_NONE;

        /** Notification categories to prioritize. Bitmask of PRIORITY_CATEGORY_* constants. */
        public final int priorityCategories;

@@ -1588,6 +1619,18 @@ public class NotificationManager {
         * PRIORITY_SENDERS_ANY, PRIORITY_SENDERS_CONTACTS, PRIORITY_SENDERS_STARRED */
        public final int priorityMessageSenders;

        /**
         * Notification senders to prioritize for conversations. One of:
         * {@link #CONVERSATION_SENDERS_NONE}, {@link #CONVERSATION_SENDERS_IMPORTANT},
         * {@link #CONVERSATION_SENDERS_ANYONE}.
         */
        public final int priorityConversationSenders;

        /**
         * @hide
         */
        public static final int CONVERSATION_SENDERS_UNSET = -1;

        /**
         * @hide
         */
@@ -1665,21 +1708,6 @@ public class NotificationManager {
                SUPPRESSED_EFFECT_NOTIFICATION_LIST
        };

        private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
                SUPPRESSED_EFFECT_SCREEN_OFF,
                SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
                SUPPRESSED_EFFECT_LIGHTS,
                SUPPRESSED_EFFECT_AMBIENT,
        };

        private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
                SUPPRESSED_EFFECT_SCREEN_ON,
                SUPPRESSED_EFFECT_PEEK,
                SUPPRESSED_EFFECT_STATUS_BAR,
                SUPPRESSED_EFFECT_BADGE,
                SUPPRESSED_EFFECT_NOTIFICATION_LIST
        };

        /**
         * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
         * Bitmask of SUPPRESSED_EFFECT_* constants.
@@ -1718,7 +1746,41 @@ public class NotificationManager {
         */
        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders) {
            this(priorityCategories, priorityCallSenders, priorityMessageSenders,
                    SUPPRESSED_EFFECTS_UNSET, STATE_UNSET);
                    SUPPRESSED_EFFECTS_UNSET, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
        }

        /**
         * Constructs a policy for Do Not Disturb priority mode behavior.
         *
         * <p>
         *     Apps that target API levels below {@link Build.VERSION_CODES#R} cannot
         *     change user-designated values to allow or disallow
         *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS}, from bypassing dnd.
         * <p>
         *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
         *     only modify the {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
         *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} bits of the suppressed visual effects field.
         *     All other suppressed effects will be ignored and reconstituted from the screen on
         *     and screen off values.
         * <p>
         *     Apps that target {@link Build.VERSION_CODES#P} or above can set any
         *     suppressed visual effects. However, if any suppressed effects >
         *     {@link #SUPPRESSED_EFFECT_SCREEN_ON} are set, {@link #SUPPRESSED_EFFECT_SCREEN_ON}
         *     and {@link #SUPPRESSED_EFFECT_SCREEN_OFF} will be ignored and reconstituted from
         *     the more specific suppressed visual effect bits. Apps should migrate to targeting
         *     specific effects instead of the deprecated {@link #SUPPRESSED_EFFECT_SCREEN_ON} and
         *     {@link #SUPPRESSED_EFFECT_SCREEN_OFF} effects.
         *
         * @param priorityCategories bitmask of categories of notifications that can bypass DND.
         * @param priorityCallSenders which callers can bypass DND.
         * @param priorityMessageSenders which message senders can bypass DND.
         * @param suppressedVisualEffects which visual interruptions should be suppressed from
         *                                notifications that are filtered by DND.
         */
        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
                int suppressedVisualEffects) {
            this(priorityCategories, priorityCallSenders, priorityMessageSenders,
                    suppressedVisualEffects, STATE_UNSET, CONVERSATION_SENDERS_UNSET);
        }

        /**
@@ -1727,7 +1789,14 @@ public class NotificationManager {
         * <p>
         *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
         *     change user-designated values to allow or disallow
         *     {@link Policy#PRIORITY_CATEGORY_ALARMS}, {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
         *     {@link Policy#PRIORITY_CATEGORY_CONVERSATIONS} from bypassing dnd. If you do need
         *     to change them, use a {@link ZenPolicy} associated with an {@link AutomaticZenRule}
         *     instead of changing the global setting.
         * <p>
         *     Apps that target API levels below {@link Build.VERSION_CODES#P} cannot
         *     change user-designated values to allow or disallow
         *     {@link Policy#PRIORITY_CATEGORY_ALARMS},
         *     {@link Policy#PRIORITY_CATEGORY_SYSTEM}, and
         *     {@link Policy#PRIORITY_CATEGORY_MEDIA} from bypassing dnd.
         * <p>
         *     Additionally, apps that target API levels below {@link Build.VERSION_CODES#P} can
@@ -1751,28 +1820,27 @@ public class NotificationManager {
         *                                notifications that are filtered by DND.
         */
        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
                int suppressedVisualEffects) {
            this.priorityCategories = priorityCategories;
            this.priorityCallSenders = priorityCallSenders;
            this.priorityMessageSenders = priorityMessageSenders;
            this.suppressedVisualEffects = suppressedVisualEffects;
            this.state = STATE_UNSET;
                int suppressedVisualEffects, int priorityConversationSenders) {
            this(priorityCategories, priorityCallSenders, priorityMessageSenders,
                    suppressedVisualEffects, STATE_UNSET, priorityConversationSenders);
        }

        /** @hide */
        public Policy(int priorityCategories, int priorityCallSenders, int priorityMessageSenders,
                int suppressedVisualEffects, int state) {
                int suppressedVisualEffects, int state, int priorityConversationSenders) {
            this.priorityCategories = priorityCategories;
            this.priorityCallSenders = priorityCallSenders;
            this.priorityMessageSenders = priorityMessageSenders;
            this.suppressedVisualEffects = suppressedVisualEffects;
            this.state = state;
            this.priorityConversationSenders = priorityConversationSenders;
        }


        /** @hide */
        public Policy(Parcel source) {
            this(source.readInt(), source.readInt(), source.readInt(), source.readInt(),
                    source.readInt());
                    source.readInt(), source.readInt());
        }

        @Override
@@ -1782,6 +1850,7 @@ public class NotificationManager {
            dest.writeInt(priorityMessageSenders);
            dest.writeInt(suppressedVisualEffects);
            dest.writeInt(state);
            dest.writeInt(priorityConversationSenders);
        }

        @Override
@@ -1792,7 +1861,7 @@ public class NotificationManager {
        @Override
        public int hashCode() {
            return Objects.hash(priorityCategories, priorityCallSenders, priorityMessageSenders,
                    suppressedVisualEffects, state);
                    suppressedVisualEffects, state, priorityConversationSenders);
        }

        @Override
@@ -1805,7 +1874,8 @@ public class NotificationManager {
                    && other.priorityMessageSenders == priorityMessageSenders
                    && suppressedVisualEffectsEqual(suppressedVisualEffects,
                    other.suppressedVisualEffects)
                    && other.state == this.state;
                    && other.state == this.state
                    && other.priorityConversationSenders == this.priorityConversationSenders;
        }

        private boolean suppressedVisualEffectsEqual(int suppressedEffects,
@@ -1867,6 +1937,8 @@ public class NotificationManager {
                    + "priorityCategories=" + priorityCategoriesToString(priorityCategories)
                    + ",priorityCallSenders=" + prioritySendersToString(priorityCallSenders)
                    + ",priorityMessageSenders=" + prioritySendersToString(priorityMessageSenders)
                    + ",priorityConvSenders="
                    + conversationSendersToString(priorityConversationSenders)
                    + ",suppressedVisualEffects="
                    + suppressedEffectsToString(suppressedVisualEffects)
                    + ",areChannelsBypassingDnd=" + (((state & STATE_CHANNELS_BYPASSING_DND) != 0)
@@ -2003,6 +2075,7 @@ public class NotificationManager {
                case PRIORITY_CATEGORY_ALARMS: return "PRIORITY_CATEGORY_ALARMS";
                case PRIORITY_CATEGORY_MEDIA: return "PRIORITY_CATEGORY_MEDIA";
                case PRIORITY_CATEGORY_SYSTEM: return "PRIORITY_CATEGORY_SYSTEM";
                case PRIORITY_CATEGORY_CONVERSATIONS: return "PRIORITY_CATEGORY_CONVERSATIONS";
                default: return "PRIORITY_CATEGORY_UNKNOWN_" + priorityCategory;
            }
        }
@@ -2016,7 +2089,25 @@ public class NotificationManager {
            }
        }

        public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR = new Parcelable.Creator<Policy>() {
        /**
         * @hide
         */
        public static @NonNull String conversationSendersToString(int priorityConversationSenders) {
            switch (priorityConversationSenders) {
                case CONVERSATION_SENDERS_ANYONE:
                    return "anyone";
                case CONVERSATION_SENDERS_IMPORTANT:
                    return "important";
                case CONVERSATION_SENDERS_NONE:
                    return "none";
                case CONVERSATION_SENDERS_UNSET:
                    return "unset";
            }
            return "invalidConversationType{" + priorityConversationSenders + "}";
        }

        public static final @android.annotation.NonNull Parcelable.Creator<Policy> CREATOR
                = new Parcelable.Creator<Policy>() {
            @Override
            public Policy createFromParcel(Parcel in) {
                return new Policy(in);
@@ -2053,6 +2144,11 @@ public class NotificationManager {
            return (priorityCategories & PRIORITY_CATEGORY_CALLS) != 0;
        }

        /** @hide **/
        public boolean allowConversations() {
            return (priorityCategories & PRIORITY_CATEGORY_CONVERSATIONS) != 0;
        }

        /** @hide **/
        public boolean allowMessages() {
            return (priorityCategories & PRIORITY_CATEGORY_MESSAGES) != 0;
@@ -2078,6 +2174,11 @@ public class NotificationManager {
            return priorityMessageSenders;
        }

        /** @hide **/
        public int allowConversationsFrom() {
            return priorityConversationSenders;
        }

        /** @hide **/
        public boolean showFullScreenIntents() {
            return (suppressedVisualEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0;
+75 −8

File changed.

Preview size limit exceeded, changes collapsed.

Loading