Merge "Notification text change should not be interruptive during post time" into sc-v2-dev
This commit is contained in:
@@ -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()),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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())) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user