Merge "Notification text change should not be interruptive during post time" into sc-v2-dev

This commit is contained in:
Chloris Kuo
2021-10-19 01:16:13 +00:00
committed by Android (Google) Code Review
10 changed files with 57 additions and 33 deletions

View File

@@ -1699,7 +1699,7 @@ public abstract class NotificationListenerService extends Service {
private ArrayList<Notification.Action> mSmartActions;
private ArrayList<CharSequence> mSmartReplies;
private boolean mCanBubble;
private boolean mVisuallyInterruptive;
private boolean mIsTextChanged;
private boolean mIsConversation;
private ShortcutInfo mShortcutInfo;
private @RankingAdjustment int mRankingAdjustment;
@@ -1736,7 +1736,7 @@ public abstract class NotificationListenerService extends Service {
out.writeTypedList(mSmartActions, flags);
out.writeCharSequenceList(mSmartReplies);
out.writeBoolean(mCanBubble);
out.writeBoolean(mVisuallyInterruptive);
out.writeBoolean(mIsTextChanged);
out.writeBoolean(mIsConversation);
out.writeParcelable(mShortcutInfo, flags);
out.writeInt(mRankingAdjustment);
@@ -1774,7 +1774,7 @@ public abstract class NotificationListenerService extends Service {
mSmartActions = in.createTypedArrayList(Notification.Action.CREATOR);
mSmartReplies = in.readCharSequenceList();
mCanBubble = in.readBoolean();
mVisuallyInterruptive = in.readBoolean();
mIsTextChanged = in.readBoolean();
mIsConversation = in.readBoolean();
mShortcutInfo = in.readParcelable(cl);
mRankingAdjustment = in.readInt();
@@ -1977,8 +1977,8 @@ public abstract class NotificationListenerService extends Service {
}
/** @hide */
public boolean visuallyInterruptive() {
return mVisuallyInterruptive;
public boolean isTextChanged() {
return mIsTextChanged;
}
/** @hide */
@@ -2033,7 +2033,7 @@ public abstract class NotificationListenerService extends Service {
int userSentiment, boolean hidden, long lastAudiblyAlertedMs,
boolean noisy, ArrayList<Notification.Action> smartActions,
ArrayList<CharSequence> smartReplies, boolean canBubble,
boolean visuallyInterruptive, boolean isConversation, ShortcutInfo shortcutInfo,
boolean isTextChanged, boolean isConversation, ShortcutInfo shortcutInfo,
int rankingAdjustment, boolean isBubble) {
mKey = key;
mRank = rank;
@@ -2055,7 +2055,7 @@ public abstract class NotificationListenerService extends Service {
mSmartActions = smartActions;
mSmartReplies = smartReplies;
mCanBubble = canBubble;
mVisuallyInterruptive = visuallyInterruptive;
mIsTextChanged = isTextChanged;
mIsConversation = isConversation;
mShortcutInfo = shortcutInfo;
mRankingAdjustment = rankingAdjustment;
@@ -2096,7 +2096,7 @@ public abstract class NotificationListenerService extends Service {
other.mSmartActions,
other.mSmartReplies,
other.mCanBubble,
other.mVisuallyInterruptive,
other.mIsTextChanged,
other.mIsConversation,
other.mShortcutInfo,
other.mRankingAdjustment,
@@ -2153,7 +2153,7 @@ public abstract class NotificationListenerService extends Service {
== (other.mSmartActions == null ? 0 : other.mSmartActions.size()))
&& Objects.equals(mSmartReplies, other.mSmartReplies)
&& Objects.equals(mCanBubble, other.mCanBubble)
&& Objects.equals(mVisuallyInterruptive, other.mVisuallyInterruptive)
&& Objects.equals(mIsTextChanged, other.mIsTextChanged)
&& Objects.equals(mIsConversation, other.mIsConversation)
// Shortcutinfo doesn't have equals either; use id
&& Objects.equals((mShortcutInfo == null ? 0 : mShortcutInfo.getId()),

View File

@@ -121,7 +121,7 @@ public class Bubble implements BubbleViewProvider {
@Nullable
private Icon mIcon;
private boolean mIsBubble;
private boolean mIsVisuallyInterruptive;
private boolean mIsTextChanged;
private boolean mIsClearable;
private boolean mShouldSuppressNotificationDot;
private boolean mShouldSuppressNotificationList;
@@ -342,12 +342,12 @@ public class Bubble implements BubbleViewProvider {
}
/**
* Sets whether this bubble is considered visually interruptive. This method is purely for
* Sets whether this bubble is considered text changed. This method is purely for
* testing.
*/
@VisibleForTesting
void setVisuallyInterruptiveForTest(boolean visuallyInterruptive) {
mIsVisuallyInterruptive = visuallyInterruptive;
void setTextChangedForTest(boolean textChanged) {
mIsTextChanged = textChanged;
}
/**
@@ -454,7 +454,7 @@ public class Bubble implements BubbleViewProvider {
mFlyoutMessage = extractFlyoutMessage(entry);
if (entry.getRanking() != null) {
mShortcutInfo = entry.getRanking().getConversationShortcutInfo();
mIsVisuallyInterruptive = entry.getRanking().visuallyInterruptive();
mIsTextChanged = entry.getRanking().isTextChanged();
if (entry.getRanking().getChannel() != null) {
mIsImportantConversation =
entry.getRanking().getChannel().isImportantConversation();
@@ -495,8 +495,8 @@ public class Bubble implements BubbleViewProvider {
return mIcon;
}
boolean isVisuallyInterruptive() {
return mIsVisuallyInterruptive;
boolean isTextChanged() {
return mIsTextChanged;
}
/**

View File

@@ -939,7 +939,7 @@ public class BubbleController {
public void updateBubble(BubbleEntry notif, boolean suppressFlyout, boolean showInShade) {
// If this is an interruptive notif, mark that it's interrupted
mSysuiProxy.setNotificationInterruption(notif.getKey());
if (!notif.getRanking().visuallyInterruptive()
if (!notif.getRanking().isTextChanged()
&& (notif.getBubbleMetadata() != null
&& !notif.getBubbleMetadata().getAutoExpandBubble())
&& mBubbleData.hasOverflowBubbleWithKey(notif.getKey())) {

View File

@@ -323,7 +323,7 @@ public class BubbleData {
}
mPendingBubbles.remove(bubble.getKey()); // No longer pending once we're here
Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey());
suppressFlyout |= !bubble.isVisuallyInterruptive();
suppressFlyout |= !bubble.isTextChanged();
if (prevBubble == null) {
// Create a new bubble

View File

@@ -131,7 +131,7 @@ public class BubbleDataTest extends ShellTestCase {
NotificationListenerService.Ranking ranking =
mock(NotificationListenerService.Ranking.class);
when(ranking.visuallyInterruptive()).thenReturn(true);
when(ranking.isTextChanged()).thenReturn(true);
mEntryInterruptive = createBubbleEntry(1, "interruptive", "package.d", ranking);
mBubbleInterruptive = new Bubble(mEntryInterruptive, mSuppressionListener, null,
mMainExecutor);
@@ -1014,15 +1014,15 @@ public class BubbleDataTest extends ShellTestCase {
}
private void sendUpdatedEntryAtTime(BubbleEntry entry, long postTime) {
sendUpdatedEntryAtTime(entry, postTime, true /* visuallyInterruptive */);
sendUpdatedEntryAtTime(entry, postTime, true /* isTextChanged */);
}
private void sendUpdatedEntryAtTime(BubbleEntry entry, long postTime,
boolean visuallyInterruptive) {
boolean textChanged) {
setPostTime(entry, postTime);
// BubbleController calls this:
Bubble b = mBubbleData.getOrCreateBubble(entry, null /* persistedBubble */);
b.setVisuallyInterruptiveForTest(visuallyInterruptive);
b.setTextChangedForTest(textChanged);
// And then this
mBubbleData.notificationEntryUpdated(b, false /* suppressFlyout*/,
true /* showInShade */);

View File

@@ -52,7 +52,7 @@ public class RankingBuilder {
private ArrayList<Notification.Action> mSmartActions = new ArrayList<>();
private ArrayList<CharSequence> mSmartReplies = new ArrayList<>();
private boolean mCanBubble = false;
private boolean mIsVisuallyInterruptive = false;
private boolean mIsTextChanged = false;
private boolean mIsConversation = false;
private ShortcutInfo mShortcutInfo = null;
private int mRankingAdjustment = 0;
@@ -81,7 +81,7 @@ public class RankingBuilder {
mSmartActions = copyList(ranking.getSmartActions());
mSmartReplies = copyList(ranking.getSmartReplies());
mCanBubble = ranking.canBubble();
mIsVisuallyInterruptive = ranking.visuallyInterruptive();
mIsTextChanged = ranking.isTextChanged();
mIsConversation = ranking.isConversation();
mShortcutInfo = ranking.getConversationShortcutInfo();
mRankingAdjustment = ranking.getRankingAdjustment();
@@ -110,7 +110,7 @@ public class RankingBuilder {
mSmartActions,
mSmartReplies,
mCanBubble,
mIsVisuallyInterruptive,
mIsTextChanged,
mIsConversation,
mShortcutInfo,
mRankingAdjustment,
@@ -189,8 +189,8 @@ public class RankingBuilder {
return this;
}
public RankingBuilder setVisuallyInterruptive(boolean interruptive) {
mIsVisuallyInterruptive = interruptive;
public RankingBuilder setTextChanged(boolean textChanged) {
mIsTextChanged = textChanged;
return this;
}

View File

@@ -7076,7 +7076,6 @@ public class NotificationManagerService extends SystemService {
r.isUpdate = true;
final boolean isInterruptive = isVisuallyInterruptive(old, r);
r.setTextChanged(isInterruptive);
r.setInterruptive(isInterruptive);
}
mNotificationsByKey.put(n.getKey(), r);
@@ -9424,7 +9423,7 @@ public class NotificationManagerService extends SystemService {
record.getSystemGeneratedSmartActions(),
record.getSmartReplies(),
record.canBubble(),
record.isInterruptive(),
record.isTextChanged(),
record.isConversation(),
record.getShortcutInfo(),
record.getRankingScore() == 0

View File

@@ -1143,6 +1143,10 @@ public final class NotificationRecord {
return mIsInterruptive;
}
public boolean isTextChanged() {
return mTextChanged;
}
/** Returns the time the notification audibly alerted the user. */
public long getLastAudiblyAlertedMs() {
return mLastAudiblyAlertedMs;

View File

@@ -118,7 +118,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
assertActionsEqual(getSmartActions(key, i), ranking.getSmartActions());
assertEquals(getSmartReplies(key, i), ranking.getSmartReplies());
assertEquals(canBubble(i), ranking.canBubble());
assertEquals(visuallyInterruptive(i), ranking.visuallyInterruptive());
assertEquals(isTextChanged(i), ranking.isTextChanged());
assertEquals(isConversation(i), ranking.isConversation());
assertEquals(getShortcutInfo(i).getId(), ranking.getConversationShortcutInfo().getId());
assertEquals(getRankingAdjustment(i), ranking.getRankingAdjustment());
@@ -189,7 +189,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
(ArrayList) tweak.getSmartActions(),
(ArrayList) tweak.getSmartReplies(),
tweak.canBubble(),
tweak.visuallyInterruptive(),
tweak.isTextChanged(),
tweak.isConversation(),
tweak.getConversationShortcutInfo(),
tweak.getRankingAdjustment(),
@@ -270,7 +270,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
getSmartActions(key, i),
getSmartReplies(key, i),
canBubble(i),
visuallyInterruptive(i),
isTextChanged(i),
isConversation(i),
getShortcutInfo(i),
getRankingAdjustment(i),
@@ -379,7 +379,7 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
return index % 4 == 0;
}
private boolean visuallyInterruptive(int index) {
private boolean isTextChanged(int index) {
return index % 4 == 0;
}

View File

@@ -3871,6 +3871,27 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r.getStats().getDismissalSentiment());
}
@Test
public void testVisuallyInterruptive_notSeen() throws Exception {
NotificationRecord original = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(original);
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, original.getSbn().getId(),
original.getSbn().getTag(), mUid, 0,
new Notification.Builder(mContext, mTestNotificationChannel.getId())
.setContentTitle("new title").build(),
UserHandle.getUserHandleForUid(mUid), null, 0);
NotificationRecord update = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
mService.addEnqueuedNotification(update);
NotificationManagerService.PostNotificationRunnable runnable =
mService.new PostNotificationRunnable(update.getKey());
runnable.run();
waitForIdle();
assertFalse(update.isInterruptive());
}
@Test
public void testApplyAdjustmentMultiUser() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);