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

Commit bd35832d authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge "Bubble API: post update when bubble notification suppression flag changes"

parents ab2fa88e f44b6837
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -8644,17 +8644,23 @@ public class Notification implements Parcelable
        public static final int FLAG_AUTO_EXPAND_BUBBLE = 0x00000001;

        /**
         * If set and the app posting the bubble is in the foreground, the bubble will
         * be posted <b>without</b> the associated notification in the notification shade.
         * Indicates whether the notification associated with the bubble is being visually
         * suppressed from the notification shade. When <code>true</code> the notification is
         * hidden, when <code>false</code> the notification shows as normal.
         *
         * <p>This flag has no effect if the app posting the bubble is not in the foreground.
         * The app is considered foreground if it is visible and on the screen, note that
         * a foreground service does not qualify.
         * </p>
         * <p>Apps sending bubbles may set this flag so that the bubble is posted <b>without</b>
         * the associated notification in the notification shade.</p>
         *
         * <p>Generally this flag should only be set if the user has performed an action to request
         * or create a bubble, or if the user has seen the content in the notification and the
         * notification is no longer relevant.</p>
         * <p>Apps sending bubbles can only apply this flag when the app is in the foreground,
         * otherwise the flag is not respected. The app is considered foreground if it is visible
         * and on the screen, note that a foreground service does not qualify.</p>
         *
         * <p>Generally this flag should only be set by the app if the user has performed an
         * action to request or create a bubble, or if the user has seen the content in the
         * notification and the notification is no longer relevant. </p>
         *
         * <p>The system will also update this flag with <code>true</code> to hide the notification
         * from the user once the bubble has been expanded. </p>
         *
         * @hide
         */
@@ -8772,6 +8778,24 @@ public class Notification implements Parcelable
        }

        /**
         * Indicates whether the notification associated with the bubble is being visually
         * suppressed from the notification shade. When <code>true</code> the notification is
         * hidden, when <code>false</code> the notification shows as normal.
         *
         * <p>Apps sending bubbles may set this flag so that the bubble is posted <b>without</b>
         * the associated notification in the notification shade.</p>
         *
         * <p>Apps sending bubbles can only apply this flag when the app is in the foreground,
         * otherwise the flag is not respected. The app is considered foreground if it is visible
         * and on the screen, note that a foreground service does not qualify.</p>
         *
         * <p>Generally the app should only set this flag if the user has performed an
         * action to request or create a bubble, or if the user has seen the content in the
         * notification and the notification is no longer relevant. </p>
         *
         * <p>The system will update this flag with <code>true</code> to hide the notification
         * from the user once the bubble has been expanded.</p>
         *
         * @return whether this bubble should suppress the notification when it is posted.
         *
         * @see BubbleMetadata.Builder#setSuppressNotification(boolean)
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ interface IStatusBarService
            in int notificationLocation, boolean modifiedBeforeSending);
    void onNotificationSettingsViewed(String key);
    void onNotificationBubbleChanged(String key, boolean isBubble);
    void onBubbleNotificationSuppressionChanged(String key, boolean isSuppressed);
    void grantInlineReplyUriPermission(String key, in Uri uri, in UserHandle user, String packageName);
    void clearInlineReplyUriPermissions(String key);

+30 −24
Original line number Diff line number Diff line
@@ -60,6 +60,14 @@ class Bubble {
    private long mLastUpdated;
    private long mLastAccessed;

    private BubbleController.NotificationSuppressionChangedListener mSuppressionListener;

    /** Whether the bubble should show a dot for the notification indicating updated content. */
    private boolean mShowBubbleUpdateDot = true;

    /** Whether flyout text should be suppressed, regardless of any other flags or state. */
    private boolean mSuppressFlyout;

    // Items that are typically loaded later
    private String mAppName;
    private ShortcutInfo mShortcutInfo;
@@ -70,20 +78,6 @@ class Bubble {
    private BubbleViewInfoTask mInflationTask;
    private boolean mInflateSynchronously;

    /**
     * Whether this notification should be shown in the shade when it is also displayed as a bubble.
     *
     * <p>When a notification is a bubble we don't show it in the shade once the bubble has been
     * expanded</p>
     */
    private boolean mShowInShadeWhenBubble = true;

    /** Whether the bubble should show a dot for the notification indicating updated content. */
    private boolean mShowBubbleUpdateDot = true;

    /** Whether flyout text should be suppressed, regardless of any other flags or state. */
    private boolean mSuppressFlyout;

    /**
     * Presentational info about the flyout.
     */
@@ -106,11 +100,13 @@ class Bubble {

    /** Used in tests when no UI is required. */
    @VisibleForTesting(visibility = PRIVATE)
    Bubble(NotificationEntry e) {
    Bubble(NotificationEntry e,
            BubbleController.NotificationSuppressionChangedListener listener) {
        mEntry = e;
        mKey = e.getKey();
        mLastUpdated = e.getSbn().getPostTime();
        mGroupId = groupId(e);
        mSuppressionListener = listener;
    }

    public String getKey() {
@@ -278,7 +274,7 @@ class Bubble {
     */
    void markAsAccessedAt(long lastAccessedMillis) {
        mLastAccessed = lastAccessedMillis;
        setShowInShade(false);
        setSuppressNotification(true);
        setShowDot(false /* show */, true /* animate */);
    }

@@ -290,20 +286,30 @@ class Bubble {
    }

    /**
     * Whether this notification should be shown in the shade when it is also displayed as a
     * bubble.
     * Whether this notification should be shown in the shade.
     */
    boolean showInShade() {
        return !mEntry.isRowDismissed() && !shouldSuppressNotification()
                && (!mEntry.isClearable() || mShowInShadeWhenBubble);
        return !shouldSuppressNotification() || !mEntry.isClearable();
    }

    /**
     * Sets whether this notification should be shown in the shade when it is also displayed as a
     * bubble.
     * Sets whether this notification should be suppressed in the shade.
     */
    void setShowInShade(boolean showInShade) {
        mShowInShadeWhenBubble = showInShade;
    void setSuppressNotification(boolean suppressNotification) {
        boolean prevShowInShade = showInShade();

        Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
        int flags = data.getFlags();
        if (suppressNotification) {
            flags |= Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
        } else {
            flags &= ~Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
        }
        data.setFlags(flags);

        if (showInShade() != prevShowInShade && mSuppressionListener != null) {
            mSuppressionListener.onBubbleNotificationSuppressionChange(this);
        }
    }

    /**
+27 −3
Original line number Diff line number Diff line
@@ -223,6 +223,17 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
        void onBubbleScreenshot(Bubble bubble);
    }

    /**
     * Listener to be notified when a bubbles' notification suppression state changes.
     */
    public interface NotificationSuppressionChangedListener {
        /**
         * Called when the notification suppression state of a bubble changes.
         */
        void onBubbleNotificationSuppressionChange(Bubble bubble);

    }

    /**
     * Listens for the current state of the status bar and updates the visibility state
     * of bubbles as needed.
@@ -303,9 +314,22 @@ public class BubbleController implements ConfigurationController.ConfigurationLi

        configurationController.addCallback(this /* configurationListener */);

        mMaxBubbles = mContext.getResources().getInteger(R.integer.bubbles_max_rendered);
        mBubbleData = data;
        mBubbleData.setListener(mBubbleDataListener);
        mMaxBubbles = mContext.getResources().getInteger(R.integer.bubbles_max_rendered);
        mBubbleData.setSuppressionChangedListener(new NotificationSuppressionChangedListener() {
            @Override
            public void onBubbleNotificationSuppressionChange(Bubble bubble) {
                // Make sure NoMan knows it's not showing in the shade anymore so anyone querying it
                // can tell.
                try {
                    mBarService.onBubbleNotificationSuppressionChanged(bubble.getKey(),
                            !bubble.showInShade());
                } catch (RemoteException e) {
                    // Bad things have happened
                }
            }
        });

        mNotificationEntryManager = entryManager;
        mNotificationEntryManager.addNotificationEntryListener(mEntryListener);
@@ -720,7 +744,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
                Bubble bubble = mBubbleData.getBubbleWithKey(key);
                boolean bubbleExtended = entry != null && entry.isBubble() && userRemovedNotif;
                if (bubbleExtended) {
                    bubble.setShowInShade(false);
                    bubble.setSuppressNotification(true);
                    bubble.setShowDot(false /* show */, true /* animate */);
                    mNotificationEntryManager.updateNotifications(
                            "BubbleController.onNotificationRemoveRequested");
@@ -747,7 +771,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
                // As far as group manager is concerned, once a child is no longer shown
                // in the shade, it is essentially removed.
                mNotificationGroupManager.onEntryRemoved(bubbleChild.getEntry());
                bubbleChild.setShowInShade(false);
                bubbleChild.setSuppressNotification(true);
                bubbleChild.setShowDot(false /* show */, true /* animate */);
            }
            // And since all children are removed, remove the summary.
+13 −3
Original line number Diff line number Diff line
@@ -134,6 +134,9 @@ public class BubbleData {
    @Nullable
    private Listener mListener;

    @Nullable
    private BubbleController.NotificationSuppressionChangedListener mSuppressionListener;

    /**
     * We track groups with summaries that aren't visibly displayed but still kept around because
     * the bubble(s) associated with the summary still exist.
@@ -158,6 +161,11 @@ public class BubbleData {
        mMaxOverflowBubbles = mContext.getResources().getInteger(R.integer.bubbles_max_overflow);
    }

    public void setSuppressionChangedListener(
            BubbleController.NotificationSuppressionChangedListener listener) {
        mSuppressionListener = listener;
    }

    public boolean hasBubbles() {
        return !mBubbles.isEmpty();
    }
@@ -219,7 +227,7 @@ public class BubbleData {
                    return b;
                }
            }
            bubble = new Bubble(entry);
            bubble = new Bubble(entry, mSuppressionListener);
            mPendingBubbles.add(bubble);
        } else {
            bubble.setEntry(entry);
@@ -258,11 +266,13 @@ public class BubbleData {
        } else if (mSelectedBubble == null) {
            setSelectedBubbleInternal(bubble);
        }

        boolean isBubbleExpandedAndSelected = mExpanded && mSelectedBubble == bubble;
        bubble.setShowInShade(!isBubbleExpandedAndSelected && showInShade);
        boolean suppress = isBubbleExpandedAndSelected || !showInShade || !bubble.showInShade();
        bubble.setSuppressNotification(suppress);
        bubble.setShowDot(!isBubbleExpandedAndSelected /* show */, true /* animate */);
        dispatchPendingChanges();

        dispatchPendingChanges();
    }

    public void notificationEntryRemoved(NotificationEntry entry, @DismissReason int reason) {
Loading