Merge "Allow NAS to mark when sensitive notification content was detected."
This commit is contained in:
committed by
Android (Google) Code Review
commit
2a5a56b711
@@ -12370,6 +12370,7 @@ package android.service.notification {
|
||||
field public static final String KEY_NOT_CONVERSATION = "key_not_conversation";
|
||||
field public static final String KEY_PEOPLE = "key_people";
|
||||
field public static final String KEY_RANKING_SCORE = "key_ranking_score";
|
||||
field public static final String KEY_SENSITIVE_CONTENT = "key_sensitive_content";
|
||||
field public static final String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
|
||||
field public static final String KEY_TEXT_REPLIES = "key_text_replies";
|
||||
field public static final String KEY_USER_SENTIMENT = "key_user_sentiment";
|
||||
@@ -12409,6 +12410,7 @@ package android.service.notification {
|
||||
|
||||
public static class NotificationListenerService.Ranking {
|
||||
method public int getProposedImportance();
|
||||
method public boolean hasSensitiveContent();
|
||||
}
|
||||
|
||||
public final class NotificationStats implements android.os.Parcelable {
|
||||
|
||||
@@ -52,7 +52,7 @@ public final class Adjustment implements Parcelable {
|
||||
/** @hide */
|
||||
@StringDef (prefix = { "KEY_" }, value = {
|
||||
KEY_CONTEXTUAL_ACTIONS, KEY_GROUP_KEY, KEY_IMPORTANCE, KEY_PEOPLE, KEY_SNOOZE_CRITERIA,
|
||||
KEY_TEXT_REPLIES, KEY_USER_SENTIMENT, KEY_IMPORTANCE_PROPOSAL
|
||||
KEY_TEXT_REPLIES, KEY_USER_SENTIMENT, KEY_IMPORTANCE_PROPOSAL, KEY_SENSITIVE_CONTENT
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Keys {}
|
||||
@@ -133,6 +133,13 @@ public final class Adjustment implements Parcelable {
|
||||
*/
|
||||
public static final String KEY_IMPORTANCE_PROPOSAL = "key_importance_proposal";
|
||||
|
||||
/**
|
||||
* Data type: boolean, when true it suggests that the content text of this notification is
|
||||
* sensitive. A notification listener can use this information to redact notifications on locked
|
||||
* devices.
|
||||
*/
|
||||
public static final String KEY_SENSITIVE_CONTENT = "key_sensitive_content";
|
||||
|
||||
/**
|
||||
* Data type: float, a ranking score from 0 (lowest) to 1 (highest).
|
||||
* Used to rank notifications inside that fall under the same classification (i.e. alerting,
|
||||
|
||||
@@ -1732,10 +1732,13 @@ public abstract class NotificationListenerService extends Service {
|
||||
private boolean mIsBubble;
|
||||
// Notification assistant importance suggestion
|
||||
private int mProposedImportance;
|
||||
// Sensitive info detected by the notification assistant
|
||||
private boolean mSensitiveContent;
|
||||
|
||||
private static final int PARCEL_VERSION = 2;
|
||||
|
||||
public Ranking() { }
|
||||
public Ranking() {
|
||||
}
|
||||
|
||||
// You can parcel it, but it's not Parcelable
|
||||
/** @hide */
|
||||
@@ -1770,6 +1773,7 @@ public abstract class NotificationListenerService extends Service {
|
||||
out.writeInt(mRankingAdjustment);
|
||||
out.writeBoolean(mIsBubble);
|
||||
out.writeInt(mProposedImportance);
|
||||
out.writeBoolean(mSensitiveContent);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -1809,6 +1813,7 @@ public abstract class NotificationListenerService extends Service {
|
||||
mRankingAdjustment = in.readInt();
|
||||
mIsBubble = in.readBoolean();
|
||||
mProposedImportance = in.readInt();
|
||||
mSensitiveContent = in.readBoolean();
|
||||
}
|
||||
|
||||
|
||||
@@ -1917,6 +1922,17 @@ public abstract class NotificationListenerService extends Service {
|
||||
return mProposedImportance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the notification text is sensitive (e.g. containing an OTP).
|
||||
*
|
||||
* @return whether the notification contains sensitive content
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public boolean hasSensitiveContent() {
|
||||
return mSensitiveContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the system has overridden the group key, then this will be non-null, and this
|
||||
* key should be used to bundle notifications.
|
||||
@@ -2081,7 +2097,8 @@ public abstract class NotificationListenerService extends Service {
|
||||
boolean noisy, ArrayList<Notification.Action> smartActions,
|
||||
ArrayList<CharSequence> smartReplies, boolean canBubble,
|
||||
boolean isTextChanged, boolean isConversation, ShortcutInfo shortcutInfo,
|
||||
int rankingAdjustment, boolean isBubble, int proposedImportance) {
|
||||
int rankingAdjustment, boolean isBubble, int proposedImportance,
|
||||
boolean sensitiveContent) {
|
||||
mKey = key;
|
||||
mRank = rank;
|
||||
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
|
||||
@@ -2108,6 +2125,7 @@ public abstract class NotificationListenerService extends Service {
|
||||
mRankingAdjustment = rankingAdjustment;
|
||||
mIsBubble = isBubble;
|
||||
mProposedImportance = proposedImportance;
|
||||
mSensitiveContent = sensitiveContent;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2149,7 +2167,8 @@ public abstract class NotificationListenerService extends Service {
|
||||
other.mShortcutInfo,
|
||||
other.mRankingAdjustment,
|
||||
other.mIsBubble,
|
||||
other.mProposedImportance);
|
||||
other.mProposedImportance,
|
||||
other.mSensitiveContent);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2209,7 +2228,8 @@ public abstract class NotificationListenerService extends Service {
|
||||
(other.mShortcutInfo == null ? 0 : other.mShortcutInfo.getId()))
|
||||
&& Objects.equals(mRankingAdjustment, other.mRankingAdjustment)
|
||||
&& Objects.equals(mIsBubble, other.mIsBubble)
|
||||
&& Objects.equals(mProposedImportance, other.mProposedImportance);
|
||||
&& Objects.equals(mProposedImportance, other.mProposedImportance)
|
||||
&& Objects.equals(mSensitiveContent, other.mSensitiveContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,30 +268,31 @@ public class NotificationListener extends NotificationListenerWithPlugins implem
|
||||
if (!rankingMap.getRanking(key, ranking)) {
|
||||
ranking.populate(
|
||||
key,
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>(),
|
||||
false,
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
false,
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
0,
|
||||
false,
|
||||
0
|
||||
/* rank= */ 0,
|
||||
/* matchesInterruptionFilter= */ false,
|
||||
/* visibilityOverride= */ 0,
|
||||
/* suppressedVisualEffects= */ 0,
|
||||
/* importance= */ 0,
|
||||
/* explanation= */ null,
|
||||
/* overrideGroupKey= */ null,
|
||||
/* channel= */ null,
|
||||
/* overridePeople= */ new ArrayList<>(),
|
||||
/* snoozeCriteria= */ new ArrayList<>(),
|
||||
/* showBadge= */ false,
|
||||
/* userSentiment= */ 0,
|
||||
/* hidden= */ false,
|
||||
/* lastAudiblyAlertedMs= */ 0,
|
||||
/* noisy= */ false,
|
||||
/* smartActions= */ new ArrayList<>(),
|
||||
/* smartReplies= */ new ArrayList<>(),
|
||||
/* canBubble= */ false,
|
||||
/* isTextChanged= */ false,
|
||||
/* isConversation= */ false,
|
||||
/* shortcutInfo= */ null,
|
||||
/* rankingAdjustment= */ 0,
|
||||
/* isBubble= */ false,
|
||||
/* proposedImportance= */ 0,
|
||||
/* sensitiveContent= */ false
|
||||
);
|
||||
}
|
||||
return ranking;
|
||||
|
||||
@@ -120,13 +120,31 @@ class TargetSdkResolverTest : SysuiTestCase() {
|
||||
private fun createRanking(key: String) = Ranking().apply {
|
||||
populate(
|
||||
key,
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
NotificationManager.IMPORTANCE_DEFAULT,
|
||||
null, null,
|
||||
null, null, null, true, 0, false, -1, false, null, null, false, false,
|
||||
false, null, 0, false, 0)
|
||||
/* rank = */ 0,
|
||||
/* matchesInterruptionFilter = */ false,
|
||||
/* visibilityOverride = */ 0,
|
||||
/* suppressedVisualEffects = */ 0,
|
||||
/* importance = */ NotificationManager.IMPORTANCE_DEFAULT,
|
||||
/* explanation = */ null,
|
||||
/* overrideGroupKey = */ null,
|
||||
/* channel = */ null,
|
||||
/* overridePeople = */ null,
|
||||
/* snoozeCriteria = */ null,
|
||||
/* showBadge = */ true,
|
||||
/* userSentiment = */ 0,
|
||||
/* hidden = */ false,
|
||||
/* lastAudiblyAlertedMs = */ -1,
|
||||
/* noisy = */ false,
|
||||
/* smartActions = */ null,
|
||||
/* smartReplies = */ null,
|
||||
/* canBubble = */ false,
|
||||
/* isTextChanged = */ false,
|
||||
/* isConversation = */ false,
|
||||
/* shortcutInfo = */ null,
|
||||
/* rankingAdjustment = */ 0,
|
||||
/* isBubble = */ false,
|
||||
/* proposedImportance = */ 0,
|
||||
/* sensitiveContent = */ false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ public class RankingBuilder {
|
||||
private int mRankingAdjustment = 0;
|
||||
private boolean mIsBubble = false;
|
||||
private int mProposedImportance = IMPORTANCE_UNSPECIFIED;
|
||||
private boolean mSensitiveContent = false;
|
||||
|
||||
public RankingBuilder() {
|
||||
}
|
||||
@@ -90,6 +91,7 @@ public class RankingBuilder {
|
||||
mRankingAdjustment = ranking.getRankingAdjustment();
|
||||
mIsBubble = ranking.isBubble();
|
||||
mProposedImportance = ranking.getProposedImportance();
|
||||
mSensitiveContent = ranking.hasSensitiveContent();
|
||||
}
|
||||
|
||||
public Ranking build() {
|
||||
@@ -119,7 +121,8 @@ public class RankingBuilder {
|
||||
mShortcutInfo,
|
||||
mRankingAdjustment,
|
||||
mIsBubble,
|
||||
mProposedImportance);
|
||||
mProposedImportance,
|
||||
mSensitiveContent);
|
||||
return ranking;
|
||||
}
|
||||
|
||||
@@ -224,6 +227,11 @@ public class RankingBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public RankingBuilder setSensitiveContent(boolean sensitiveContent) {
|
||||
mSensitiveContent = sensitiveContent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RankingBuilder setUserSentiment(int userSentiment) {
|
||||
mUserSentiment = userSentiment;
|
||||
return this;
|
||||
|
||||
@@ -8693,7 +8693,8 @@ public class NotificationManagerService extends SystemService {
|
||||
r.getImportance(),
|
||||
r.getRankingScore(),
|
||||
r.isConversation(),
|
||||
r.getProposedImportance());
|
||||
r.getProposedImportance(),
|
||||
r.hasSensitiveContent());
|
||||
extractorDataBefore.put(r.getKey(), extractorData);
|
||||
mRankingHelper.extractSignals(r);
|
||||
}
|
||||
@@ -9989,7 +9990,8 @@ public class NotificationManagerService extends SystemService {
|
||||
? RANKING_UNCHANGED
|
||||
: (record.getRankingScore() > 0 ? RANKING_PROMOTED : RANKING_DEMOTED),
|
||||
record.getNotification().isBubbleNotification(),
|
||||
record.getProposedImportance()
|
||||
record.getProposedImportance(),
|
||||
record.hasSensitiveContent()
|
||||
);
|
||||
rankings.add(ranking);
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ public final class NotificationRecord {
|
||||
// are sorted.
|
||||
private boolean mPendingLogUpdate = false;
|
||||
private int mProposedImportance = IMPORTANCE_UNSPECIFIED;
|
||||
private boolean mSensitiveContent = false;
|
||||
|
||||
public NotificationRecord(Context context, StatusBarNotification sbn,
|
||||
NotificationChannel channel) {
|
||||
@@ -503,6 +504,7 @@ public final class NotificationRecord {
|
||||
pw.println(prefix + "mProposedImportance="
|
||||
+ NotificationListenerService.Ranking.importanceToString(mProposedImportance));
|
||||
pw.println(prefix + "mIsAppImportanceLocked=" + mIsAppImportanceLocked);
|
||||
pw.println(prefix + "mSensitiveContent=" + mSensitiveContent);
|
||||
pw.println(prefix + "mIntercept=" + mIntercept);
|
||||
pw.println(prefix + "mHidden==" + mHidden);
|
||||
pw.println(prefix + "mGlobalSortKey=" + mGlobalSortKey);
|
||||
@@ -747,6 +749,12 @@ public final class NotificationRecord {
|
||||
Adjustment.KEY_IMPORTANCE_PROPOSAL,
|
||||
Integer.toString(mProposedImportance));
|
||||
}
|
||||
if (signals.containsKey(Adjustment.KEY_SENSITIVE_CONTENT)) {
|
||||
mSensitiveContent = signals.getBoolean(Adjustment.KEY_SENSITIVE_CONTENT);
|
||||
EventLogTags.writeNotificationAdjusted(getKey(),
|
||||
Adjustment.KEY_SENSITIVE_CONTENT,
|
||||
Boolean.toString(mSensitiveContent));
|
||||
}
|
||||
if (!signals.isEmpty() && adjustment.getIssuer() != null) {
|
||||
mAdjustmentIssuer = adjustment.getIssuer();
|
||||
}
|
||||
@@ -883,6 +891,13 @@ public final class NotificationRecord {
|
||||
return mProposedImportance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the notification contains sensitive content detected by the assistant.
|
||||
*/
|
||||
public boolean hasSensitiveContent() {
|
||||
return mSensitiveContent;
|
||||
}
|
||||
|
||||
public float getRankingScore() {
|
||||
return mRankingScore;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public final class NotificationRecordExtractorData {
|
||||
private final float mRankingScore;
|
||||
private final boolean mIsConversation;
|
||||
private final int mProposedImportance;
|
||||
private final boolean mSensitiveContent;
|
||||
|
||||
NotificationRecordExtractorData(int position, int visibility, boolean showBadge,
|
||||
boolean allowBubble, boolean isBubble, NotificationChannel channel, String groupKey,
|
||||
@@ -53,7 +54,7 @@ public final class NotificationRecordExtractorData {
|
||||
Integer userSentiment, Integer suppressVisually,
|
||||
ArrayList<Notification.Action> systemSmartActions,
|
||||
ArrayList<CharSequence> smartReplies, int importance, float rankingScore,
|
||||
boolean isConversation, int proposedImportance) {
|
||||
boolean isConversation, int proposedImportance, boolean sensitiveContent) {
|
||||
mPosition = position;
|
||||
mVisibility = visibility;
|
||||
mShowBadge = showBadge;
|
||||
@@ -71,6 +72,7 @@ public final class NotificationRecordExtractorData {
|
||||
mRankingScore = rankingScore;
|
||||
mIsConversation = isConversation;
|
||||
mProposedImportance = proposedImportance;
|
||||
mSensitiveContent = sensitiveContent;
|
||||
}
|
||||
|
||||
// Returns whether the provided NotificationRecord differs from the cached data in any way.
|
||||
@@ -90,7 +92,8 @@ public final class NotificationRecordExtractorData {
|
||||
|| !Objects.equals(mSystemSmartActions, r.getSystemGeneratedSmartActions())
|
||||
|| !Objects.equals(mSmartReplies, r.getSmartReplies())
|
||||
|| mImportance != r.getImportance()
|
||||
|| mProposedImportance != r.getProposedImportance();
|
||||
|| mProposedImportance != r.getProposedImportance()
|
||||
|| mSensitiveContent != r.hasSensitiveContent();
|
||||
}
|
||||
|
||||
// Returns whether the NotificationRecord has a change from this data for which we should
|
||||
@@ -113,6 +116,7 @@ public final class NotificationRecordExtractorData {
|
||||
|| mImportance != r.getImportance()
|
||||
|| !r.rankingScoreMatches(mRankingScore)
|
||||
|| mIsConversation != r.isConversation()
|
||||
|| mProposedImportance != r.getProposedImportance();
|
||||
|| mProposedImportance != r.getProposedImportance()
|
||||
|| mSensitiveContent != r.hasSensitiveContent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1737,15 +1737,33 @@ public final class DataManagerTest {
|
||||
NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
|
||||
invocationOnMock.getArguments()[1];
|
||||
ranking.populate(
|
||||
(String) invocationOnMock.getArguments()[0],
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
/* key= */ (String) invocationOnMock.getArguments()[0],
|
||||
/* rank= */ 0,
|
||||
/* matchesInterruptionFilter= */ false,
|
||||
/* visibilityOverride= */ 0,
|
||||
/* suppressedVisualEffects= */ 0,
|
||||
mParentNotificationChannel.getImportance(),
|
||||
null, null,
|
||||
mParentNotificationChannel, null, null, true, 0, false, -1, false, null, null,
|
||||
false, false, false, null, 0, false, 0);
|
||||
/* explanation= */ null,
|
||||
/* overrideGroupKey= */ null,
|
||||
mParentNotificationChannel,
|
||||
/* overridePeople= */ null,
|
||||
/* snoozeCriteria= */ null,
|
||||
/* showBadge= */ true,
|
||||
/* userSentiment= */ 0,
|
||||
/* hidden= */ false,
|
||||
/* lastAudiblyAlertedMs= */ -1,
|
||||
/* noisy= */ false,
|
||||
/* smartActions= */ null,
|
||||
/* smartReplies= */ null,
|
||||
/* canBubble= */ false,
|
||||
/* isTextChanged= */ false,
|
||||
/* isConversation= */ false,
|
||||
/* shortcutInfo= */ null,
|
||||
/* rankingAdjustment= */ 0,
|
||||
/* isBubble= */ false,
|
||||
/* proposedImportance= */ 0,
|
||||
/* sensitiveContent= */ false
|
||||
);
|
||||
return true;
|
||||
}).when(mRankingMap).getRanking(eq(key),
|
||||
any(NotificationListenerService.Ranking.class));
|
||||
@@ -1763,15 +1781,33 @@ public final class DataManagerTest {
|
||||
NotificationListenerService.Ranking ranking = (NotificationListenerService.Ranking)
|
||||
invocationOnMock.getArguments()[1];
|
||||
ranking.populate(
|
||||
(String) invocationOnMock.getArguments()[0],
|
||||
0,
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
mNotificationChannel.getImportance(),
|
||||
null, null,
|
||||
mNotificationChannel, null, null, true, 0, false, -1, false, null, null, false,
|
||||
false, false, null, 0, false, 0);
|
||||
/* key= */ (String) invocationOnMock.getArguments()[0],
|
||||
/* rank= */ 0,
|
||||
/* matchesInterruptionFilter= */ false,
|
||||
/* visibilityOverride= */ 0,
|
||||
/* suppressedVisualEffects= */ 0,
|
||||
mParentNotificationChannel.getImportance(),
|
||||
/* explanation= */ null,
|
||||
/* overrideGroupKey= */ null,
|
||||
mParentNotificationChannel,
|
||||
/* overridePeople= */ null,
|
||||
/* snoozeCriteria= */ null,
|
||||
/* showBadge= */ true,
|
||||
/* userSentiment= */ 0,
|
||||
/* hidden= */ false,
|
||||
/* lastAudiblyAlertedMs= */ -1,
|
||||
/* noisy= */ false,
|
||||
/* smartActions= */ null,
|
||||
/* smartReplies= */ null,
|
||||
/* canBubble= */ false,
|
||||
/* isTextChanged= */ false,
|
||||
/* isConversation= */ false,
|
||||
/* shortcutInfo= */ null,
|
||||
/* rankingAdjustment= */ 0,
|
||||
/* isBubble= */ false,
|
||||
/* proposedImportance= */ 0,
|
||||
/* sensitiveContent= */ false
|
||||
);
|
||||
return true;
|
||||
}).when(mRankingMap).getRanking(eq(CUSTOM_KEY),
|
||||
any(NotificationListenerService.Ranking.class));
|
||||
|
||||
@@ -194,7 +194,8 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
tweak.getConversationShortcutInfo(),
|
||||
tweak.getRankingAdjustment(),
|
||||
tweak.isBubble(),
|
||||
tweak.getProposedImportance()
|
||||
tweak.getProposedImportance(),
|
||||
tweak.hasSensitiveContent()
|
||||
);
|
||||
assertNotEquals(nru, nru2);
|
||||
}
|
||||
@@ -276,7 +277,8 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
getShortcutInfo(i),
|
||||
getRankingAdjustment(i),
|
||||
isBubble(i),
|
||||
getProposedImportance(i)
|
||||
getProposedImportance(i),
|
||||
hasSensitiveContent(i)
|
||||
);
|
||||
rankings[i] = ranking;
|
||||
}
|
||||
@@ -408,6 +410,10 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
return index % 5 - 1;
|
||||
}
|
||||
|
||||
private boolean hasSensitiveContent(int index) {
|
||||
return index % 3 == 0;
|
||||
}
|
||||
|
||||
private boolean isBubble(int index) {
|
||||
return index % 4 == 0;
|
||||
}
|
||||
@@ -450,6 +456,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
b.getConversationShortcutInfo().getId());
|
||||
assertActionsEqual(a.getSmartActions(), b.getSmartActions());
|
||||
assertEquals(a.getProposedImportance(), b.getProposedImportance());
|
||||
assertEquals(a.hasSensitiveContent(), b.hasSensitiveContent());
|
||||
}
|
||||
|
||||
private void detailedAssertEquals(RankingMap a, RankingMap b) {
|
||||
|
||||
@@ -19,29 +19,20 @@ package com.android.server.notification;
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
import static android.app.NotificationManager.IMPORTANCE_LOW;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.Adjustment;
|
||||
import android.service.notification.SnoozeCriterion;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
|
||||
import com.android.server.UiServiceTestCase;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NotificationRecordExtractorDataTest extends UiServiceTestCase {
|
||||
|
||||
@Test
|
||||
@@ -65,7 +56,8 @@ public class NotificationRecordExtractorDataTest extends UiServiceTestCase {
|
||||
r.getImportance(),
|
||||
r.getRankingScore(),
|
||||
r.isConversation(),
|
||||
r.getProposedImportance());
|
||||
r.getProposedImportance(),
|
||||
r.hasSensitiveContent());
|
||||
|
||||
assertFalse(extractorData.hasDiffForRankingLocked(r, 1));
|
||||
assertFalse(extractorData.hasDiffForLoggingLocked(r, 1));
|
||||
@@ -92,7 +84,8 @@ public class NotificationRecordExtractorDataTest extends UiServiceTestCase {
|
||||
r.getImportance(),
|
||||
r.getRankingScore(),
|
||||
r.isConversation(),
|
||||
r.getProposedImportance());
|
||||
r.getProposedImportance(),
|
||||
r.hasSensitiveContent());
|
||||
|
||||
Bundle signals = new Bundle();
|
||||
signals.putInt(Adjustment.KEY_IMPORTANCE_PROPOSAL, IMPORTANCE_HIGH);
|
||||
@@ -104,6 +97,40 @@ public class NotificationRecordExtractorDataTest extends UiServiceTestCase {
|
||||
assertTrue(extractorData.hasDiffForLoggingLocked(r, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasDiffs_sensitiveContentChange() {
|
||||
NotificationRecord r = generateRecord();
|
||||
|
||||
NotificationRecordExtractorData extractorData = new NotificationRecordExtractorData(
|
||||
1,
|
||||
r.getPackageVisibilityOverride(),
|
||||
r.canShowBadge(),
|
||||
r.canBubble(),
|
||||
r.getNotification().isBubbleNotification(),
|
||||
r.getChannel(),
|
||||
r.getGroupKey(),
|
||||
r.getPeopleOverride(),
|
||||
r.getSnoozeCriteria(),
|
||||
r.getUserSentiment(),
|
||||
r.getSuppressedVisualEffects(),
|
||||
r.getSystemGeneratedSmartActions(),
|
||||
r.getSmartReplies(),
|
||||
r.getImportance(),
|
||||
r.getRankingScore(),
|
||||
r.isConversation(),
|
||||
r.getProposedImportance(),
|
||||
r.hasSensitiveContent());
|
||||
|
||||
Bundle signals = new Bundle();
|
||||
signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, true);
|
||||
Adjustment adjustment = new Adjustment("pkg", r.getKey(), signals, "", 0);
|
||||
r.addAdjustment(adjustment);
|
||||
r.applyAdjustments();
|
||||
|
||||
assertTrue(extractorData.hasDiffForRankingLocked(r, 1));
|
||||
assertTrue(extractorData.hasDiffForLoggingLocked(r, 1));
|
||||
}
|
||||
|
||||
private NotificationRecord generateRecord() {
|
||||
NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
|
||||
final Notification.Builder builder = new Notification.Builder(getContext())
|
||||
|
||||
@@ -787,6 +787,24 @@ public class NotificationRecordTest extends UiServiceTestCase {
|
||||
assertFalse(record.getIsAppImportanceLocked());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSensitiveContent() {
|
||||
StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
|
||||
true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
|
||||
false /* lights */, false /* defaultLights */, groupId /* group */);
|
||||
NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
|
||||
|
||||
assertFalse(record.hasSensitiveContent());
|
||||
|
||||
Bundle signals = new Bundle();
|
||||
signals.putBoolean(Adjustment.KEY_SENSITIVE_CONTENT, true);
|
||||
record.addAdjustment(new Adjustment(mPkg, record.getKey(), signals, null, sbn.getUserId()));
|
||||
|
||||
record.applyAdjustments();
|
||||
|
||||
assertTrue(record.hasSensitiveContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsInterruptive_textChanged_notSeen() {
|
||||
StatusBarNotification sbn = getNotification(PKG_O, false /* noisy */,
|
||||
|
||||
Reference in New Issue
Block a user