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

Commit 09db3de7 authored by Priyanka Advani (xWF)'s avatar Priyanka Advani (xWF) Committed by Android (Google) Code Review
Browse files

Revert "Hold classifications for noisy notifications"

This reverts commit 25cf5547.

Reason for revert: Droidmonitor created revert due to b/437220061. Will be verifying through ABTD before submission.

Fix: 437220061
Change-Id: I313fee58df611bfe76f5e381cfaad29d498d0a9d
parent 25cf5547
Loading
Loading
Loading
Loading
+19 −87
Original line number Diff line number Diff line
@@ -20,14 +20,8 @@ import static android.service.notification.Adjustment.KEY_UNCLASSIFY;
import static android.service.notification.Flags.notificationForceGrouping;

import android.content.Context;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.List;

/**
 * Applies adjustments from the group helper and notification assistant
 */
@@ -36,14 +30,6 @@ public class NotificationAdjustmentExtractor implements NotificationSignalExtrac
    private static final boolean DBG = false;
    private GroupHelper mGroupHelper;

    /** Length of time (in milliseconds) that a noisy notification will stay in its non-bundled
     * classification.
     */
    @VisibleForTesting
    static final long HANG_TIME_MS = 30000;

    @VisibleForTesting
    InjectedTime mInjectedTimeMs = null;

    public void initialize(Context ctx, NotificationUsageStats usageStats) {
        if (DBG) Slog.d(TAG, "Initializing  " + getClass().getSimpleName() + ".");
@@ -57,73 +43,12 @@ public class NotificationAdjustmentExtractor implements NotificationSignalExtrac

        final boolean hasAdjustedClassification = record.hasAdjustment(KEY_TYPE);
        final boolean removedClassification = record.hasAdjustment(KEY_UNCLASSIFY);

        if (Flags.showNoisyBundledNotifications()
                && android.service.notification.Flags.notificationClassification()
                && hasAdjustedClassification && record.getLastAudiblyAlertedMs() > 0) {
            record.applyAdjustments(new ArraySet<>(new String[] {KEY_TYPE}));

            return getClassificationReconsideration(record);
        }

        record.applyAdjustments();

        if (notificationForceGrouping()
                && android.service.notification.Flags.notificationClassification()) {
            // Classification adjustments trigger regrouping
            if (mGroupHelper != null && (hasAdjustedClassification || removedClassification)) {
                return getRegroupReconsideration(
                        record, hasAdjustedClassification, removedClassification);
            }
        }

        return null;
    }

    @Override
    public void setConfig(RankingConfig config) {
        // config is not used
    }

    @Override
    public void setZenHelper(ZenModeHelper helper) {

    }

    @Override
    public void setGroupHelper(GroupHelper groupHelper) {
        mGroupHelper = groupHelper;
    }

    private long getCurrentTime() {
        if (mInjectedTimeMs != null) {
            return mInjectedTimeMs.getCurrentTimeMillis();
        }
        return System.currentTimeMillis();
    }

    private RankingReconsideration getClassificationReconsideration(NotificationRecord record) {
        return new RankingReconsideration(record.getKey(), HANG_TIME_MS) {
            @Override
            public void work() {
                // pass
            }

            @Override
            public void applyChangesLocked(NotificationRecord record) {
                if ((getCurrentTime() - record.getLastAudiblyAlertedMs()) >= HANG_TIME_MS) {
                    record.applyAdjustments();
                    getRegroupReconsideration(record, true, false).applyChangesLocked(record);
                }
            }
        };
    }

    // The notification channel of the record has changed such that it's now moving to a new
    // UI section. We need to change the record's grouping to make sure it's not in a group
    // for the wrong section
    private RankingReconsideration getRegroupReconsideration(NotificationRecord record,
            boolean hasAdjustedClassification, boolean removedClassification) {
                return new RankingReconsideration(record.getKey(), 0) {
                    @Override
                    public void work() {
@@ -144,16 +69,23 @@ public class NotificationAdjustmentExtractor implements NotificationSignalExtrac
                    }
                };
            }
        }

    static class InjectedTime {
        private final long mCurrentTimeMillis;
        return null;
    }

        InjectedTime(long time) {
            mCurrentTimeMillis = time;
    @Override
    public void setConfig(RankingConfig config) {
        // config is not used
    }

        long getCurrentTimeMillis() {
            return mCurrentTimeMillis;
    @Override
    public void setZenHelper(ZenModeHelper helper) {

    }

    @Override
    public void setGroupHelper(GroupHelper groupHelper) {
        mGroupHelper = groupHelper;
    }
}
+51 −128
Original line number Diff line number Diff line
@@ -21,20 +21,7 @@ import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.service.notification.Adjustment.KEY_CONTEXTUAL_ACTIONS;
import static android.service.notification.Adjustment.KEY_GROUP_KEY;
import static android.service.notification.Adjustment.KEY_IMPORTANCE;
import static android.service.notification.Adjustment.KEY_IMPORTANCE_PROPOSAL;
import static android.service.notification.Adjustment.KEY_NOT_CONVERSATION;
import static android.service.notification.Adjustment.KEY_PEOPLE;
import static android.service.notification.Adjustment.KEY_RANKING_SCORE;
import static android.service.notification.Adjustment.KEY_SENSITIVE_CONTENT;
import static android.service.notification.Adjustment.KEY_SNOOZE_CRITERIA;
import static android.service.notification.Adjustment.KEY_SUMMARIZATION;
import static android.service.notification.Adjustment.KEY_TEXT_REPLIES;
import static android.service.notification.Adjustment.KEY_TYPE;
import static android.service.notification.Adjustment.KEY_UNCLASSIFY;
import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;

@@ -721,13 +708,6 @@ public final class NotificationRecord {
                this.getSbn().getNotification());
    }

    @VisibleForTesting
    int getPendingAdjustmentCount() {
        synchronized (mAdjustments) {
            return mAdjustments.size();
        }
    }

    public boolean hasAdjustment(String key) {
        synchronized (mAdjustments) {
            for (Adjustment adjustment : mAdjustments) {
@@ -746,160 +726,113 @@ public final class NotificationRecord {
    }

    public void applyAdjustments() {
        applyAdjustments(new ArraySet<>());
    }

    public void applyAdjustments(@NonNull ArraySet<String> keysToSkip) {
        long now = System.currentTimeMillis();
        synchronized (mAdjustments) {
            for (int i = mAdjustments.size() - 1; i >= 0; i--) {
                Adjustment adjustment = mAdjustments.get(i);
            for (Adjustment adjustment: mAdjustments) {
                Bundle signals = adjustment.getSignals();
                if (signals.containsKey(KEY_PEOPLE) && !keysToSkip.contains(KEY_PEOPLE)) {
                if (signals.containsKey(Adjustment.KEY_PEOPLE)) {
                    final ArrayList<String> people =
                            adjustment.getSignals().getStringArrayList(KEY_PEOPLE);
                            adjustment.getSignals().getStringArrayList(Adjustment.KEY_PEOPLE);
                    setPeopleOverride(people);
                    EventLogTags.writeNotificationAdjusted(getKey(), KEY_PEOPLE, people.toString());
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_PEOPLE);
                    }
                    EventLogTags.writeNotificationAdjusted(
                            getKey(), Adjustment.KEY_PEOPLE, people.toString());
                }
                if (signals.containsKey(KEY_SNOOZE_CRITERIA)
                        && !keysToSkip.contains(KEY_SNOOZE_CRITERIA)) {
                if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
                    final ArrayList<SnoozeCriterion> snoozeCriterionList =
                            adjustment.getSignals().getParcelableArrayList(
                                    KEY_SNOOZE_CRITERIA,
                                    Adjustment.KEY_SNOOZE_CRITERIA,
                                    android.service.notification.SnoozeCriterion.class);
                    setSnoozeCriteria(snoozeCriterionList);
                    EventLogTags.writeNotificationAdjusted(getKey(), KEY_SNOOZE_CRITERIA,
                    EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_SNOOZE_CRITERIA,
                            snoozeCriterionList.toString());
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_SNOOZE_CRITERIA);
                    }
                }
                if (signals.containsKey(KEY_GROUP_KEY) && !keysToSkip.contains(KEY_GROUP_KEY)) {
                if (signals.containsKey(Adjustment.KEY_GROUP_KEY)) {
                    final String groupOverrideKey =
                            adjustment.getSignals().getString(KEY_GROUP_KEY);
                            adjustment.getSignals().getString(Adjustment.KEY_GROUP_KEY);
                    setOverrideGroupKey(groupOverrideKey);
                    EventLogTags.writeNotificationAdjusted(getKey(), KEY_GROUP_KEY,
                    EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_GROUP_KEY,
                            groupOverrideKey);
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_GROUP_KEY);
                }
                }
                if (signals.containsKey(KEY_USER_SENTIMENT)
                        && !keysToSkip.contains(KEY_USER_SENTIMENT)) {
                if (signals.containsKey(Adjustment.KEY_USER_SENTIMENT)) {
                    // Only allow user sentiment update from assistant if user hasn't already
                    // expressed a preference for this channel
                    if (!mIsAppImportanceLocked
                            && (getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0) {
                        setUserSentiment(adjustment.getSignals().getInt(
                                KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
                                Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
                        EventLogTags.writeNotificationAdjusted(getKey(),
                                KEY_USER_SENTIMENT,
                                Adjustment.KEY_USER_SENTIMENT,
                                Integer.toString(getUserSentiment()));
                        if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                            signals.remove(KEY_USER_SENTIMENT);
                        }
                    }
                }
                if (signals.containsKey(KEY_CONTEXTUAL_ACTIONS)
                        && !keysToSkip.contains(KEY_CONTEXTUAL_ACTIONS)) {
                if (signals.containsKey(Adjustment.KEY_CONTEXTUAL_ACTIONS)) {
                    setSystemGeneratedSmartActions(
                            signals.getParcelableArrayList(KEY_CONTEXTUAL_ACTIONS,
                            signals.getParcelableArrayList(Adjustment.KEY_CONTEXTUAL_ACTIONS,
                                    android.app.Notification.Action.class));
                    EventLogTags.writeNotificationAdjusted(getKey(),
                            KEY_CONTEXTUAL_ACTIONS, getSystemGeneratedSmartActions().toString());
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_CONTEXTUAL_ACTIONS);
                    }
                            Adjustment.KEY_CONTEXTUAL_ACTIONS,
                            getSystemGeneratedSmartActions().toString());
                }
                if (signals.containsKey(KEY_TEXT_REPLIES)
                        && !keysToSkip.contains(KEY_TEXT_REPLIES)) {
                    setSmartReplies(signals.getCharSequenceArrayList(KEY_TEXT_REPLIES));
                    EventLogTags.writeNotificationAdjusted(getKey(), KEY_TEXT_REPLIES,
                if (signals.containsKey(Adjustment.KEY_TEXT_REPLIES)) {
                    setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_TEXT_REPLIES));
                    EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_TEXT_REPLIES,
                            getSmartReplies().toString());
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_TEXT_REPLIES);
                }
                }
                if (signals.containsKey(KEY_IMPORTANCE) && !keysToSkip.contains(KEY_IMPORTANCE)) {
                    int importance = signals.getInt(KEY_IMPORTANCE);
                if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) {
                    int importance = signals.getInt(Adjustment.KEY_IMPORTANCE);
                    importance = Math.max(IMPORTANCE_UNSPECIFIED, importance);
                    importance = Math.min(IMPORTANCE_HIGH, importance);
                    setAssistantImportance(importance);
                    EventLogTags.writeNotificationAdjusted(getKey(), KEY_IMPORTANCE,
                    EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_IMPORTANCE,
                            Integer.toString(importance));
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_IMPORTANCE);
                    }
                }
                if (signals.containsKey(KEY_RANKING_SCORE)
                        && !keysToSkip.contains(KEY_RANKING_SCORE)) {
                    mRankingScore = signals.getFloat(KEY_RANKING_SCORE);
                    EventLogTags.writeNotificationAdjusted(getKey(), KEY_RANKING_SCORE,
                if (signals.containsKey(Adjustment.KEY_RANKING_SCORE)) {
                    mRankingScore = signals.getFloat(Adjustment.KEY_RANKING_SCORE);
                    EventLogTags.writeNotificationAdjusted(getKey(), Adjustment.KEY_RANKING_SCORE,
                            Float.toString(mRankingScore));
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_RANKING_SCORE);
                }
                }
                if (signals.containsKey(KEY_NOT_CONVERSATION)
                        && !keysToSkip.contains(KEY_NOT_CONVERSATION)) {
                    mIsNotConversationOverride = signals.getBoolean(KEY_NOT_CONVERSATION);
                if (signals.containsKey(Adjustment.KEY_NOT_CONVERSATION)) {
                    mIsNotConversationOverride = signals.getBoolean(
                            Adjustment.KEY_NOT_CONVERSATION);
                    EventLogTags.writeNotificationAdjusted(getKey(),
                            KEY_NOT_CONVERSATION, Boolean.toString(mIsNotConversationOverride));
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_NOT_CONVERSATION);
                    }
                            Adjustment.KEY_NOT_CONVERSATION,
                            Boolean.toString(mIsNotConversationOverride));
                }
                if (signals.containsKey(KEY_IMPORTANCE_PROPOSAL)
                        && !keysToSkip.contains(KEY_IMPORTANCE_PROPOSAL)) {
                    mProposedImportance = signals.getInt(KEY_IMPORTANCE_PROPOSAL);
                if (signals.containsKey(Adjustment.KEY_IMPORTANCE_PROPOSAL)) {
                    mProposedImportance = signals.getInt(Adjustment.KEY_IMPORTANCE_PROPOSAL);
                    EventLogTags.writeNotificationAdjusted(getKey(),
                            KEY_IMPORTANCE_PROPOSAL,
                            Adjustment.KEY_IMPORTANCE_PROPOSAL,
                            Integer.toString(mProposedImportance));
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_IMPORTANCE_PROPOSAL);
                }
                }
                if (signals.containsKey(KEY_SENSITIVE_CONTENT)
                        && !keysToSkip.contains(KEY_SENSITIVE_CONTENT)) {
                    mSensitiveContent = signals.getBoolean(KEY_SENSITIVE_CONTENT);
                if (signals.containsKey(Adjustment.KEY_SENSITIVE_CONTENT)) {
                    mSensitiveContent = signals.getBoolean(Adjustment.KEY_SENSITIVE_CONTENT);
                    EventLogTags.writeNotificationAdjusted(getKey(),
                            KEY_SENSITIVE_CONTENT, Boolean.toString(mSensitiveContent));
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_SENSITIVE_CONTENT);
                    }
                            Adjustment.KEY_SENSITIVE_CONTENT,
                            Boolean.toString(mSensitiveContent));
                }
                if (android.service.notification.Flags.notificationClassification()) {
                    if (signals.containsKey(KEY_TYPE) && !keysToSkip.contains(KEY_TYPE)) {
                    if (signals.containsKey(Adjustment.KEY_TYPE)) {
                        // Store original channel visibility before re-assigning channel
                        if (!NotificationChannel.SYSTEM_RESERVED_IDS.contains(mChannel.getId())) {
                            setOriginalChannelVisibility(mChannel.getLockscreenVisibility());
                        }
                        updateNotificationChannel(signals.getParcelable(KEY_TYPE,
                        updateNotificationChannel(signals.getParcelable(Adjustment.KEY_TYPE,
                                NotificationChannel.class));
                        EventLogTags.writeNotificationAdjusted(
                                getKey(), KEY_TYPE, mChannel.getId());
                        if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                            signals.remove(KEY_TYPE);
                        }
                        EventLogTags.writeNotificationAdjusted(getKey(),
                                Adjustment.KEY_TYPE,
                                mChannel.getId());
                    }
                    if (signals.containsKey(KEY_UNCLASSIFY)
                            && !keysToSkip.contains(KEY_UNCLASSIFY)) {
                    if (signals.containsKey(Adjustment.KEY_UNCLASSIFY)) {
                        // reset original channel visibility as we're returning to the original
                        setOriginalChannelVisibility(NotificationManager.VISIBILITY_NO_OVERRIDE);
                        updateNotificationChannel(signals.getParcelable(KEY_UNCLASSIFY,
                        updateNotificationChannel(signals.getParcelable(Adjustment.KEY_UNCLASSIFY,
                                NotificationChannel.class));
                        EventLogTags.writeNotificationAdjusted(getKey(),
                                KEY_UNCLASSIFY, mChannel.getId());
                        if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                            signals.remove(KEY_UNCLASSIFY);
                        }
                                Adjustment.KEY_UNCLASSIFY, mChannel.getId());
                    }
                }
                if ((android.app.Flags.nmSummarizationUi() || android.app.Flags.nmSummarization())
                        && signals.containsKey(KEY_SUMMARIZATION)
                        && !keysToSkip.contains(KEY_SUMMARIZATION)) {
                        && signals.containsKey(KEY_SUMMARIZATION)) {
                    CharSequence summary = signals.getCharSequence(KEY_SUMMARIZATION,
                            signals.getString(KEY_SUMMARIZATION));
                    if (summary != null) {
@@ -909,25 +842,15 @@ public final class NotificationRecord {
                    }
                    EventLogTags.writeNotificationAdjusted(getKey(),
                            KEY_SUMMARIZATION, Boolean.toString(mSummarization != null));
                    if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                        signals.remove(KEY_SUMMARIZATION);
                    }
                }
                if (!signals.isEmpty() && adjustment.getIssuer() != null) {
                    mAdjustmentIssuer = adjustment.getIssuer();
                }
                if (com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                    if (adjustment.getSignals().isEmpty()) {
                        mAdjustments.remove(i);
            }
                }
            }
            if (!com.android.server.notification.Flags.showNoisyBundledNotifications()) {
                // We have now gotten all the information out of the adjustments and can forget them
            // We have now gotten all the information out of the adjustments and can forget them.
            mAdjustments.clear();
        }
    }
    }

    String getAdjustmentIssuer() {
        return mAdjustmentIssuer;
+3 −2
Original line number Diff line number Diff line
@@ -20,8 +20,9 @@ import android.content.Context;
import com.android.internal.compat.IPlatformCompat;

/**
 * Extracts signals that will be useful to provide to notification listeners and caches them
 * on the {@link NotificationRecord} object.
 * Extracts signals that will be useful to the {@link NotificationComparator} and caches them
 *  on the {@link NotificationRecord} object. These annotations will
 *  not be passed on to {@link android.service.notification.NotificationListenerService}s.
 *
 *  If you add a new Extractor be sure to add it to R.array.config_notificationSignalExtractors.
 */
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.server.notification;

import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.text.TextUtils.formatSimple;

import android.annotation.NonNull;
+0 −10
Original line number Diff line number Diff line
@@ -230,13 +230,3 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "show_noisy_bundled_notifications"
  namespace: "notifications"
  description: "If a classification arrived late and the notification made noise, show the notification as unclassified temporarily"
  bug: "430573835"
  metadata {
      purpose: PURPOSE_BUGFIX
    }
}
Loading