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

Commit 7f059781 authored by Iavor-Valentin Iftime's avatar Iavor-Valentin Iftime Committed by Android (Google) Code Review
Browse files

Merge changes from topic "notif_force_group" into main

* changes:
  Notification API hardening: add FLAG_SILENT
  Notification API hardening: forced auto-grouping
parents c837d233 a7064b97
Loading
Loading
Loading
Loading
+62 −3
Original line number Diff line number Diff line
@@ -762,6 +762,16 @@ public class Notification implements Parcelable
    @FlaggedApi(Flags.FLAG_LIFETIME_EXTENSION_REFACTOR)
    public static final int FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY = 0x00010000;
    /**
     * Bit to be bitwise-ored into the {@link #flags} field that should be
     * set by the system if this notification is silent.
     *
     * This flag is for internal use only; applications cannot set this flag directly.
     * @hide
     */
    @FlaggedApi(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
    public static final int FLAG_SILENT = 1 << 17;  //0x00020000
    private static final List<Class<? extends Style>> PLATFORM_STYLE_CLASSES = Arrays.asList(
            BigTextStyle.class, BigPictureStyle.class, InboxStyle.class, MediaStyle.class,
            DecoratedCustomViewStyle.class, DecoratedMediaCustomViewStyle.class,
@@ -784,7 +794,8 @@ public class Notification implements Parcelable
            FLAG_BUBBLE,
            FLAG_NO_DISMISS,
            FLAG_FSI_REQUESTED_BUT_DENIED,
            FLAG_USER_INITIATED_JOB
            FLAG_USER_INITIATED_JOB,
            FLAG_SILENT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface NotificationFlags{};
@@ -1692,6 +1703,7 @@ public class Notification implements Parcelable
     *
     * @hide
     */
    @Deprecated
    public static final String GROUP_KEY_SILENT = "silent";
    private int mGroupAlertBehavior = GROUP_ALERT_ALL;
@@ -3984,6 +3996,13 @@ public class Notification implements Parcelable
            }
        }
        if (android.service.notification.Flags.notificationSilentFlag()) {
            if ((flags & FLAG_SILENT) != 0) {
                flagStrings.add("SILENT");
                flags &= ~FLAG_SILENT;
            }
        }
        if (flagStrings.isEmpty()) {
            return "0";
        }
@@ -4122,6 +4141,17 @@ public class Notification implements Parcelable
        return mGroupAlertBehavior;
    }
    /**
     * Sets which type of notifications in a group are responsible for audibly alerting the
     * user. See {@link #GROUP_ALERT_ALL}, {@link #GROUP_ALERT_CHILDREN},
     * {@link #GROUP_ALERT_SUMMARY}.
     * @param groupAlertBehavior
     * @hide
     */
    public void setGroupAlertBehavior(@GroupAlertBehavior int groupAlertBehavior) {
        mGroupAlertBehavior = groupAlertBehavior;
    }
    /**
     * Returns the bubble metadata that will be used to display app content in a floating window
     * over the existing foreground activity.
@@ -4308,6 +4338,31 @@ public class Notification implements Parcelable
        return contextualActions;
    }
    /**
     * Sets the FLAG_SILENT flag to mark the notification as silent and clears the group key.
     * @hide
     */
    public void fixSilentGroup() {
        if (android.service.notification.Flags.notificationSilentFlag()) {
            if (GROUP_KEY_SILENT.equals(mGroupKey)) {
                mGroupKey = null;
                flags |= FLAG_SILENT;
            }
        }
    }
    /**
     * @return whether this notification is silent. See {@link Builder#setSilent()}
     * @hide
     */
    public boolean isSilent() {
        if (android.service.notification.Flags.notificationSilentFlag()) {
            return (flags & Notification.FLAG_SILENT) != 0;
        } else {
            return GROUP_KEY_SILENT.equals(getGroup()) && suppressAlertingDueToGrouping();
        }
    }
    /**
     * Builder class for {@link Notification} objects.
     *
@@ -4759,9 +4814,13 @@ public class Notification implements Parcelable
            mN.defaults &= ~DEFAULT_VIBRATE;
            setDefaults(mN.defaults);
            if (android.service.notification.Flags.notificationSilentFlag()) {
                mN.flags |= FLAG_SILENT;
            } else {
                if (TextUtils.isEmpty(mN.mGroupKey)) {
                    setGroup(GROUP_KEY_SILENT);
                }
            }
            return this;
        }
+5 −1
Original line number Diff line number Diff line
@@ -176,8 +176,12 @@ public class StatusBarNotification implements Parcelable {

    private String groupKey() {
        if (overrideGroupKey != null) {
            if (Flags.notificationForceGrouping()) {
                return overrideGroupKey;
            } else {
                return user.getIdentifier() + "|" + pkg + "|" + "g:" + overrideGroupKey;
            }
        }
        final String group = getNotification().getGroup();
        final String sortKey = getNotification().getSortKey();
        if (group == null && sortKey == null) {
+14 −0
Original line number Diff line number Diff line
@@ -44,3 +44,17 @@ flag {
    description: "Allows the NAS to classify notifications"
    bug: "343988084"
}

flag {
  name: "notification_force_grouping"
  namespace: "systemui"
  description: "This flag controls the forced auto-grouping feature"
  bug: "336488844"
}

flag {
  name: "notification_silent_flag"
  namespace: "systemui"
  description: "Guards the new FLAG_SILENT Notification flag"
  bug: "336488844"
}
 No newline at end of file
+17 −1
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.text.Spannable;
@@ -545,12 +547,26 @@ public class NotificationTest {
    }

    @Test
    @DisableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
    public void testBuilder_setSilent_emptyGroupKey_groupKeySilent() {
        Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId")
                .setGroup("")
                .setSilent(true)
                .build();
        assertEquals(GROUP_KEY_SILENT, emptyGroupKeyNotif.getGroup());
        assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(GROUP_KEY_SILENT);
        assertThat(emptyGroupKeyNotif.isSilent()).isTrue();
    }

    @Test
    @EnableFlags(android.service.notification.Flags.FLAG_NOTIFICATION_SILENT_FLAG)
    public void testBuilder_setSilent_flagSilent() {
        final String groupKey = "groupKey";
        Notification emptyGroupKeyNotif = new Notification.Builder(mContext, "channelId")
            .setGroup(groupKey)
            .setSilent(true)
            .build();
        assertThat(emptyGroupKeyNotif.getGroup()).isEqualTo(groupKey);
        assertThat(emptyGroupKeyNotif.isSilent()).isTrue();
    }

    @Test
+10 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.SystemProperties
import android.provider.Settings
import android.provider.Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED
import android.provider.Settings.Global.HEADS_UP_OFF
import android.service.notification.Flags
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage
@@ -221,6 +222,15 @@ class HunGroupAlertBehaviorSuppressor() :
        entry.sbn.let { it.isGroup && it.notification.suppressAlertingDueToGrouping() }
}

class HunSilentNotificationSuppressor() :
    VisualInterruptionFilter(
        types = setOf(PEEK, PULSE),
        reason = "notification isSilent"
    ) {
    override fun shouldSuppress(entry: NotificationEntry) =
        entry.sbn.let { Flags.notificationSilentFlag() && it.notification.isSilent }
}

class HunJustLaunchedFsiSuppressor() :
    VisualInterruptionFilter(types = setOf(PEEK, PULSE), reason = "just launched FSI") {
    override fun shouldSuppress(entry: NotificationEntry) = entry.hasJustLaunchedFullScreenIntent()
Loading