1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.notification;
17 
18 import android.app.Notification;
19 import android.app.NotificationChannel;
20 import android.service.notification.SnoozeCriterion;
21 
22 import java.util.ArrayList;
23 import java.util.Objects;
24 
25 /**
26  * Class that stores any field in a NotificationRecord that can change via an extractor.
27  * Used to cache previous data used in a sort.
28  */
29 public final class NotificationRecordExtractorData {
30     private final int mPosition;
31     private final int mVisibility;
32     private final boolean mShowBadge;
33     private final boolean mAllowBubble;
34     private final boolean mIsBubble;
35     private final NotificationChannel mChannel;
36     private final String mGroupKey;
37     private final ArrayList<String> mOverridePeople;
38     private final ArrayList<SnoozeCriterion> mSnoozeCriteria;
39     private final Integer mUserSentiment;
40     private final Integer mSuppressVisually;
41     private final ArrayList<Notification.Action> mSystemSmartActions;
42     private final ArrayList<CharSequence> mSmartReplies;
43     private final int mImportance;
44 
45     // These fields may not trigger a reranking but diffs here may be logged.
46     private final float mRankingScore;
47     private final boolean mIsConversation;
48     private final int mProposedImportance;
49     private final boolean mSensitiveContent;
50 
NotificationRecordExtractorData(int position, int visibility, boolean showBadge, boolean allowBubble, boolean isBubble, NotificationChannel channel, String groupKey, ArrayList<String> overridePeople, ArrayList<SnoozeCriterion> snoozeCriteria, Integer userSentiment, Integer suppressVisually, ArrayList<Notification.Action> systemSmartActions, ArrayList<CharSequence> smartReplies, int importance, float rankingScore, boolean isConversation, int proposedImportance, boolean sensitiveContent)51     NotificationRecordExtractorData(int position, int visibility, boolean showBadge,
52             boolean allowBubble, boolean isBubble, NotificationChannel channel, String groupKey,
53             ArrayList<String> overridePeople, ArrayList<SnoozeCriterion> snoozeCriteria,
54             Integer userSentiment, Integer suppressVisually,
55             ArrayList<Notification.Action> systemSmartActions,
56             ArrayList<CharSequence> smartReplies, int importance, float rankingScore,
57             boolean isConversation, int proposedImportance, boolean sensitiveContent) {
58         mPosition = position;
59         mVisibility = visibility;
60         mShowBadge = showBadge;
61         mAllowBubble = allowBubble;
62         mIsBubble = isBubble;
63         mChannel = channel;
64         mGroupKey = groupKey;
65         mOverridePeople = overridePeople;
66         mSnoozeCriteria = snoozeCriteria;
67         mUserSentiment = userSentiment;
68         mSuppressVisually = suppressVisually;
69         mSystemSmartActions = systemSmartActions;
70         mSmartReplies = smartReplies;
71         mImportance = importance;
72         mRankingScore = rankingScore;
73         mIsConversation = isConversation;
74         mProposedImportance = proposedImportance;
75         mSensitiveContent = sensitiveContent;
76     }
77 
78     // Returns whether the provided NotificationRecord differs from the cached data in any way.
79     // Should be guarded by mNotificationLock; not annotated here as this class is static.
hasDiffForRankingLocked(NotificationRecord r, int newPosition)80     boolean hasDiffForRankingLocked(NotificationRecord r, int newPosition) {
81         return mPosition != newPosition
82                 || mVisibility != r.getPackageVisibilityOverride()
83                 || mShowBadge != r.canShowBadge()
84                 || mAllowBubble != r.canBubble()
85                 || mIsBubble != r.getNotification().isBubbleNotification()
86                 || !Objects.equals(mChannel, r.getChannel())
87                 || !Objects.equals(mGroupKey, r.getGroupKey())
88                 || !Objects.equals(mOverridePeople, r.getPeopleOverride())
89                 || !Objects.equals(mSnoozeCriteria, r.getSnoozeCriteria())
90                 || !Objects.equals(mUserSentiment, r.getUserSentiment())
91                 || !Objects.equals(mSuppressVisually, r.getSuppressedVisualEffects())
92                 || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
93                 || !Objects.equals(mSmartReplies, r.getSmartReplies())
94                 || mImportance != r.getImportance()
95                 || mProposedImportance != r.getProposedImportance()
96                 || mSensitiveContent != r.hasSensitiveContent();
97     }
98 
99     // Returns whether the NotificationRecord has a change from this data for which we should
100     // log an update. This method specifically targets fields that may be changed via
101     // adjustments from the assistant.
102     //
103     // Fields here are the union of things in NotificationRecordLogger.shouldLogReported
104     // and NotificationRecord.applyAdjustments.
105     //
106     // Should be guarded by mNotificationLock; not annotated here as this class is static.
hasDiffForLoggingLocked(NotificationRecord r, int newPosition)107     boolean hasDiffForLoggingLocked(NotificationRecord r, int newPosition) {
108         return mPosition != newPosition
109                 || !Objects.equals(mChannel, r.getChannel())
110                 || !Objects.equals(mGroupKey, r.getGroupKey())
111                 || !Objects.equals(mOverridePeople, r.getPeopleOverride())
112                 || !Objects.equals(mSnoozeCriteria, r.getSnoozeCriteria())
113                 || !Objects.equals(mUserSentiment, r.getUserSentiment())
114                 || !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
115                 || !Objects.equals(mSmartReplies, r.getSmartReplies())
116                 || mImportance != r.getImportance()
117                 || !r.rankingScoreMatches(mRankingScore)
118                 || mIsConversation != r.isConversation()
119                 || mProposedImportance != r.getProposedImportance()
120                 || mSensitiveContent != r.hasSensitiveContent();
121     }
122 }
123