Merge "Dramatically simplify NotificationRankingUpdate." into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d4d9b233b2
@@ -42,7 +42,6 @@ import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
@@ -53,7 +52,6 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
@@ -64,8 +62,8 @@ import com.android.internal.os.SomeArgs;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A service that receives calls from the system when new notifications are
|
||||
@@ -1442,7 +1440,7 @@ public abstract class NotificationListenerService extends Service {
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
public final void applyUpdateLocked(NotificationRankingUpdate update) {
|
||||
mRankingMap = new RankingMap(update);
|
||||
mRankingMap = update.getRankingMap();
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@@ -1480,14 +1478,14 @@ public abstract class NotificationListenerService extends Service {
|
||||
*/
|
||||
public static final int USER_SENTIMENT_POSITIVE = 1;
|
||||
|
||||
/** @hide */
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "USER_SENTIMENT_" }, value = {
|
||||
USER_SENTIMENT_NEGATIVE, USER_SENTIMENT_NEUTRAL, USER_SENTIMENT_POSITIVE
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface UserSentiment {}
|
||||
|
||||
private String mKey;
|
||||
private @NonNull String mKey;
|
||||
private int mRank = -1;
|
||||
private boolean mIsAmbient;
|
||||
private boolean mMatchesInterruptionFilter;
|
||||
@@ -1512,7 +1510,70 @@ public abstract class NotificationListenerService extends Service {
|
||||
private ArrayList<CharSequence> mSmartReplies;
|
||||
private boolean mCanBubble;
|
||||
|
||||
public Ranking() {}
|
||||
private static final int PARCEL_VERSION = 2;
|
||||
|
||||
public Ranking() { }
|
||||
|
||||
// You can parcel it, but it's not Parcelable
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
final long start = out.dataPosition();
|
||||
out.writeInt(PARCEL_VERSION);
|
||||
out.writeString(mKey);
|
||||
out.writeInt(mRank);
|
||||
out.writeBoolean(mIsAmbient);
|
||||
out.writeBoolean(mMatchesInterruptionFilter);
|
||||
out.writeInt(mVisibilityOverride);
|
||||
out.writeInt(mSuppressedVisualEffects);
|
||||
out.writeInt(mImportance);
|
||||
out.writeCharSequence(mImportanceExplanation);
|
||||
out.writeString(mOverrideGroupKey);
|
||||
out.writeParcelable(mChannel, flags);
|
||||
out.writeStringList(mOverridePeople);
|
||||
out.writeTypedList(mSnoozeCriteria, flags);
|
||||
out.writeBoolean(mShowBadge);
|
||||
out.writeInt(mUserSentiment);
|
||||
out.writeBoolean(mHidden);
|
||||
out.writeLong(mLastAudiblyAlertedMs);
|
||||
out.writeBoolean(mNoisy);
|
||||
out.writeTypedList(mSmartActions, flags);
|
||||
out.writeCharSequenceList(mSmartReplies);
|
||||
out.writeBoolean(mCanBubble);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@VisibleForTesting
|
||||
public Ranking(Parcel in) {
|
||||
final ClassLoader cl = getClass().getClassLoader();
|
||||
|
||||
final int version = in.readInt();
|
||||
if (version != PARCEL_VERSION) {
|
||||
throw new IllegalArgumentException("malformed Ranking parcel: " + in + " version "
|
||||
+ version + ", expected " + PARCEL_VERSION);
|
||||
}
|
||||
mKey = in.readString();
|
||||
mRank = in.readInt();
|
||||
mIsAmbient = in.readBoolean();
|
||||
mMatchesInterruptionFilter = in.readBoolean();
|
||||
mVisibilityOverride = in.readInt();
|
||||
mSuppressedVisualEffects = in.readInt();
|
||||
mImportance = in.readInt();
|
||||
mImportanceExplanation = in.readCharSequence(); // may be null
|
||||
mOverrideGroupKey = in.readString(); // may be null
|
||||
mChannel = (NotificationChannel) in.readParcelable(cl); // may be null
|
||||
mOverridePeople = in.createStringArrayList();
|
||||
mSnoozeCriteria = in.createTypedArrayList(SnoozeCriterion.CREATOR);
|
||||
mShowBadge = in.readBoolean();
|
||||
mUserSentiment = in.readInt();
|
||||
mHidden = in.readBoolean();
|
||||
mLastAudiblyAlertedMs = in.readLong();
|
||||
mNoisy = in.readBoolean();
|
||||
mSmartActions = in.createTypedArrayList(Notification.Action.CREATOR);
|
||||
mSmartReplies = in.readCharSequenceList();
|
||||
mCanBubble = in.readBoolean();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the key of the notification this Ranking applies to.
|
||||
@@ -1736,6 +1797,31 @@ public abstract class NotificationListenerService extends Service {
|
||||
mCanBubble = canBubble;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void populate(Ranking other) {
|
||||
populate(other.mKey,
|
||||
other.mRank,
|
||||
other.mMatchesInterruptionFilter,
|
||||
other.mVisibilityOverride,
|
||||
other.mSuppressedVisualEffects,
|
||||
other.mImportance,
|
||||
other.mImportanceExplanation,
|
||||
other.mOverrideGroupKey,
|
||||
other.mChannel,
|
||||
other.mOverridePeople,
|
||||
other.mSnoozeCriteria,
|
||||
other.mShowBadge,
|
||||
other.mUserSentiment,
|
||||
other.mHidden,
|
||||
other.mLastAudiblyAlertedMs,
|
||||
other.mNoisy,
|
||||
other.mSmartActions,
|
||||
other.mSmartReplies,
|
||||
other.mCanBubble);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
@@ -1758,6 +1844,35 @@ public abstract class NotificationListenerService extends Service {
|
||||
return "UNKNOWN(" + String.valueOf(importance) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Ranking other = (Ranking) o;
|
||||
return Objects.equals(mKey, other.mKey)
|
||||
&& Objects.equals(mRank, other.mRank)
|
||||
&& Objects.equals(mMatchesInterruptionFilter, other.mMatchesInterruptionFilter)
|
||||
&& Objects.equals(mVisibilityOverride, other.mVisibilityOverride)
|
||||
&& Objects.equals(mSuppressedVisualEffects, other.mSuppressedVisualEffects)
|
||||
&& Objects.equals(mImportance, other.mImportance)
|
||||
&& Objects.equals(mImportanceExplanation, other.mImportanceExplanation)
|
||||
&& Objects.equals(mOverrideGroupKey, other.mOverrideGroupKey)
|
||||
&& Objects.equals(mChannel, other.mChannel)
|
||||
&& Objects.equals(mOverridePeople, other.mOverridePeople)
|
||||
&& Objects.equals(mSnoozeCriteria, other.mSnoozeCriteria)
|
||||
&& Objects.equals(mShowBadge, other.mShowBadge)
|
||||
&& Objects.equals(mUserSentiment, other.mUserSentiment)
|
||||
&& Objects.equals(mHidden, other.mHidden)
|
||||
&& Objects.equals(mLastAudiblyAlertedMs, other.mLastAudiblyAlertedMs)
|
||||
&& Objects.equals(mNoisy, other.mNoisy)
|
||||
// Action.equals() doesn't exist so let's just compare list lengths
|
||||
&& ((mSmartActions == null ? 0 : mSmartActions.size())
|
||||
== (other.mSmartActions == null ? 0 : other.mSmartActions.size()))
|
||||
&& Objects.equals(mSmartReplies, other.mSmartReplies)
|
||||
&& Objects.equals(mCanBubble, other.mCanBubble);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1769,30 +1884,74 @@ public abstract class NotificationListenerService extends Service {
|
||||
* notifications active at the time of retrieval.
|
||||
*/
|
||||
public static class RankingMap implements Parcelable {
|
||||
private final NotificationRankingUpdate mRankingUpdate;
|
||||
private ArrayMap<String,Integer> mRanks;
|
||||
private ArraySet<Object> mIntercepted;
|
||||
private ArrayMap<String, Integer> mVisibilityOverrides;
|
||||
private ArrayMap<String, Integer> mSuppressedVisualEffects;
|
||||
private ArrayMap<String, Integer> mImportance;
|
||||
private ArrayMap<String, String> mImportanceExplanation;
|
||||
private ArrayMap<String, String> mOverrideGroupKeys;
|
||||
private ArrayMap<String, NotificationChannel> mChannels;
|
||||
private ArrayMap<String, ArrayList<String>> mOverridePeople;
|
||||
private ArrayMap<String, ArrayList<SnoozeCriterion>> mSnoozeCriteria;
|
||||
private ArrayMap<String, Boolean> mShowBadge;
|
||||
private ArrayMap<String, Integer> mUserSentiment;
|
||||
private ArrayMap<String, Boolean> mHidden;
|
||||
private ArrayMap<String, Long> mLastAudiblyAlerted;
|
||||
private ArrayMap<String, Boolean> mNoisy;
|
||||
private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
|
||||
private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
|
||||
private boolean[] mCanBubble;
|
||||
private ArrayList<String> mOrderedKeys = new ArrayList<>();
|
||||
// Note: all String keys should be intern'd as pointers into mOrderedKeys
|
||||
private ArrayMap<String, Ranking> mRankings = new ArrayMap<>();
|
||||
|
||||
private RankingMap(NotificationRankingUpdate rankingUpdate) {
|
||||
mRankingUpdate = rankingUpdate;
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RankingMap(Ranking[] rankings) {
|
||||
for (int i = 0; i < rankings.length; i++) {
|
||||
final String key = rankings[i].getKey();
|
||||
mOrderedKeys.add(key);
|
||||
mRankings.put(key, rankings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// -- parcelable interface --
|
||||
|
||||
private RankingMap(Parcel in) {
|
||||
final ClassLoader cl = getClass().getClassLoader();
|
||||
final int count = in.readInt();
|
||||
mOrderedKeys.ensureCapacity(count);
|
||||
mRankings.ensureCapacity(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
final Ranking r = new Ranking(in);
|
||||
final String key = r.getKey();
|
||||
mOrderedKeys.add(key);
|
||||
mRankings.put(key, r);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
RankingMap other = (RankingMap) o;
|
||||
|
||||
return mOrderedKeys.equals(other.mOrderedKeys)
|
||||
&& mRankings.equals(other.mRankings);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
final int count = mOrderedKeys.size();
|
||||
out.writeInt(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
mRankings.get(mOrderedKeys.get(i)).writeToParcel(out, flags);
|
||||
}
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
|
||||
@Override
|
||||
public RankingMap createFromParcel(Parcel source) {
|
||||
return new RankingMap(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RankingMap[] newArray(int size) {
|
||||
return new RankingMap[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Request the list of notification keys in their current ranking
|
||||
* order.
|
||||
@@ -1800,7 +1959,7 @@ public abstract class NotificationListenerService extends Service {
|
||||
* @return An array of active notification keys, in their ranking order.
|
||||
*/
|
||||
public String[] getOrderedKeys() {
|
||||
return mRankingUpdate.getOrderedKeys();
|
||||
return mOrderedKeys.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1808,381 +1967,26 @@ public abstract class NotificationListenerService extends Service {
|
||||
* with the given key.
|
||||
*
|
||||
* @return true if a valid key has been passed and outRanking has
|
||||
* been populated; false otherwise
|
||||
* been populated; false otherwise
|
||||
*/
|
||||
public boolean getRanking(String key, Ranking outRanking) {
|
||||
int rank = getRank(key);
|
||||
outRanking.populate(key, rank, !isIntercepted(key),
|
||||
getVisibilityOverride(key), getSuppressedVisualEffects(key),
|
||||
getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
|
||||
getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
|
||||
getShowBadge(key), getUserSentiment(key), getHidden(key),
|
||||
getLastAudiblyAlerted(key), getNoisy(key), getSmartActions(key),
|
||||
getSmartReplies(key), canBubble(key));
|
||||
return rank >= 0;
|
||||
}
|
||||
|
||||
private int getRank(String key) {
|
||||
synchronized (this) {
|
||||
if (mRanks == null) {
|
||||
buildRanksLocked();
|
||||
}
|
||||
if (mRankings.containsKey(key)) {
|
||||
outRanking.populate(mRankings.get(key));
|
||||
return true;
|
||||
}
|
||||
Integer rank = mRanks.get(key);
|
||||
return rank != null ? rank : -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isIntercepted(String key) {
|
||||
synchronized (this) {
|
||||
if (mIntercepted == null) {
|
||||
buildInterceptedSetLocked();
|
||||
}
|
||||
}
|
||||
return mIntercepted.contains(key);
|
||||
/**
|
||||
* Get a reference to the actual Ranking object corresponding to the key.
|
||||
* Used only by unit tests.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public Ranking getRawRankingObject(String key) {
|
||||
return mRankings.get(key);
|
||||
}
|
||||
|
||||
private int getVisibilityOverride(String key) {
|
||||
synchronized (this) {
|
||||
if (mVisibilityOverrides == null) {
|
||||
buildVisibilityOverridesLocked();
|
||||
}
|
||||
}
|
||||
Integer override = mVisibilityOverrides.get(key);
|
||||
if (override == null) {
|
||||
return Ranking.VISIBILITY_NO_OVERRIDE;
|
||||
}
|
||||
return override.intValue();
|
||||
}
|
||||
|
||||
private int getSuppressedVisualEffects(String key) {
|
||||
synchronized (this) {
|
||||
if (mSuppressedVisualEffects == null) {
|
||||
buildSuppressedVisualEffectsLocked();
|
||||
}
|
||||
}
|
||||
Integer suppressed = mSuppressedVisualEffects.get(key);
|
||||
if (suppressed == null) {
|
||||
return 0;
|
||||
}
|
||||
return suppressed.intValue();
|
||||
}
|
||||
|
||||
private int getImportance(String key) {
|
||||
synchronized (this) {
|
||||
if (mImportance == null) {
|
||||
buildImportanceLocked();
|
||||
}
|
||||
}
|
||||
Integer importance = mImportance.get(key);
|
||||
if (importance == null) {
|
||||
return NotificationManager.IMPORTANCE_DEFAULT;
|
||||
}
|
||||
return importance.intValue();
|
||||
}
|
||||
|
||||
private String getImportanceExplanation(String key) {
|
||||
synchronized (this) {
|
||||
if (mImportanceExplanation == null) {
|
||||
buildImportanceExplanationLocked();
|
||||
}
|
||||
}
|
||||
return mImportanceExplanation.get(key);
|
||||
}
|
||||
|
||||
private String getOverrideGroupKey(String key) {
|
||||
synchronized (this) {
|
||||
if (mOverrideGroupKeys == null) {
|
||||
buildOverrideGroupKeys();
|
||||
}
|
||||
}
|
||||
return mOverrideGroupKeys.get(key);
|
||||
}
|
||||
|
||||
private NotificationChannel getChannel(String key) {
|
||||
synchronized (this) {
|
||||
if (mChannels == null) {
|
||||
buildChannelsLocked();
|
||||
}
|
||||
}
|
||||
return mChannels.get(key);
|
||||
}
|
||||
|
||||
private ArrayList<String> getOverridePeople(String key) {
|
||||
synchronized (this) {
|
||||
if (mOverridePeople == null) {
|
||||
buildOverridePeopleLocked();
|
||||
}
|
||||
}
|
||||
return mOverridePeople.get(key);
|
||||
}
|
||||
|
||||
private ArrayList<SnoozeCriterion> getSnoozeCriteria(String key) {
|
||||
synchronized (this) {
|
||||
if (mSnoozeCriteria == null) {
|
||||
buildSnoozeCriteriaLocked();
|
||||
}
|
||||
}
|
||||
return mSnoozeCriteria.get(key);
|
||||
}
|
||||
|
||||
private boolean getShowBadge(String key) {
|
||||
synchronized (this) {
|
||||
if (mShowBadge == null) {
|
||||
buildShowBadgeLocked();
|
||||
}
|
||||
}
|
||||
Boolean showBadge = mShowBadge.get(key);
|
||||
return showBadge == null ? false : showBadge.booleanValue();
|
||||
}
|
||||
|
||||
private int getUserSentiment(String key) {
|
||||
synchronized (this) {
|
||||
if (mUserSentiment == null) {
|
||||
buildUserSentimentLocked();
|
||||
}
|
||||
}
|
||||
Integer userSentiment = mUserSentiment.get(key);
|
||||
return userSentiment == null
|
||||
? Ranking.USER_SENTIMENT_NEUTRAL : userSentiment.intValue();
|
||||
}
|
||||
|
||||
private boolean getHidden(String key) {
|
||||
synchronized (this) {
|
||||
if (mHidden == null) {
|
||||
buildHiddenLocked();
|
||||
}
|
||||
}
|
||||
Boolean hidden = mHidden.get(key);
|
||||
return hidden == null ? false : hidden.booleanValue();
|
||||
}
|
||||
|
||||
private long getLastAudiblyAlerted(String key) {
|
||||
synchronized (this) {
|
||||
if (mLastAudiblyAlerted == null) {
|
||||
buildLastAudiblyAlertedLocked();
|
||||
}
|
||||
}
|
||||
Long lastAudibleAlerted = mLastAudiblyAlerted.get(key);
|
||||
return lastAudibleAlerted == null ? -1 : lastAudibleAlerted.longValue();
|
||||
}
|
||||
|
||||
private boolean getNoisy(String key) {
|
||||
synchronized (this) {
|
||||
if (mNoisy == null) {
|
||||
buildNoisyLocked();
|
||||
}
|
||||
}
|
||||
Boolean noisy = mNoisy.get(key);
|
||||
return noisy == null ? false : noisy.booleanValue();
|
||||
}
|
||||
|
||||
private ArrayList<Notification.Action> getSmartActions(String key) {
|
||||
synchronized (this) {
|
||||
if (mSmartActions == null) {
|
||||
buildSmartActions();
|
||||
}
|
||||
}
|
||||
return mSmartActions.get(key);
|
||||
}
|
||||
|
||||
private ArrayList<CharSequence> getSmartReplies(String key) {
|
||||
synchronized (this) {
|
||||
if (mSmartReplies == null) {
|
||||
buildSmartReplies();
|
||||
}
|
||||
}
|
||||
return mSmartReplies.get(key);
|
||||
}
|
||||
|
||||
private boolean canBubble(String key) {
|
||||
synchronized (this) {
|
||||
if (mRanks == null) {
|
||||
buildRanksLocked();
|
||||
}
|
||||
if (mCanBubble == null) {
|
||||
mCanBubble = mRankingUpdate.getCanBubble();
|
||||
}
|
||||
}
|
||||
int keyIndex = mRanks.getOrDefault(key, -1);
|
||||
return keyIndex >= 0 ? mCanBubble[keyIndex] : false;
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildRanksLocked() {
|
||||
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
|
||||
mRanks = new ArrayMap<>(orderedKeys.length);
|
||||
for (int i = 0; i < orderedKeys.length; i++) {
|
||||
String key = orderedKeys[i];
|
||||
mRanks.put(key, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildInterceptedSetLocked() {
|
||||
String[] dndInterceptedKeys = mRankingUpdate.getInterceptedKeys();
|
||||
mIntercepted = new ArraySet<>(dndInterceptedKeys.length);
|
||||
Collections.addAll(mIntercepted, dndInterceptedKeys);
|
||||
}
|
||||
|
||||
private ArrayMap<String, Integer> buildIntMapFromBundle(Bundle bundle) {
|
||||
ArrayMap<String, Integer> newMap = new ArrayMap<>(bundle.size());
|
||||
for (String key : bundle.keySet()) {
|
||||
newMap.put(key, bundle.getInt(key));
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private ArrayMap<String, String> buildStringMapFromBundle(Bundle bundle) {
|
||||
ArrayMap<String, String> newMap = new ArrayMap<>(bundle.size());
|
||||
for (String key : bundle.keySet()) {
|
||||
newMap.put(key, bundle.getString(key));
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private ArrayMap<String, Boolean> buildBooleanMapFromBundle(Bundle bundle) {
|
||||
ArrayMap<String, Boolean> newMap = new ArrayMap<>(bundle.size());
|
||||
for (String key : bundle.keySet()) {
|
||||
newMap.put(key, bundle.getBoolean(key));
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
private ArrayMap<String, Long> buildLongMapFromBundle(Bundle bundle) {
|
||||
ArrayMap<String, Long> newMap = new ArrayMap<>(bundle.size());
|
||||
for (String key : bundle.keySet()) {
|
||||
newMap.put(key, bundle.getLong(key));
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildVisibilityOverridesLocked() {
|
||||
mVisibilityOverrides = buildIntMapFromBundle(mRankingUpdate.getVisibilityOverrides());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildSuppressedVisualEffectsLocked() {
|
||||
mSuppressedVisualEffects =
|
||||
buildIntMapFromBundle(mRankingUpdate.getSuppressedVisualEffects());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildImportanceLocked() {
|
||||
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
|
||||
int[] importance = mRankingUpdate.getImportance();
|
||||
mImportance = new ArrayMap<>(orderedKeys.length);
|
||||
for (int i = 0; i < orderedKeys.length; i++) {
|
||||
String key = orderedKeys[i];
|
||||
mImportance.put(key, importance[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildImportanceExplanationLocked() {
|
||||
mImportanceExplanation =
|
||||
buildStringMapFromBundle(mRankingUpdate.getImportanceExplanation());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildOverrideGroupKeys() {
|
||||
mOverrideGroupKeys = buildStringMapFromBundle(mRankingUpdate.getOverrideGroupKeys());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildChannelsLocked() {
|
||||
Bundle channels = mRankingUpdate.getChannels();
|
||||
mChannels = new ArrayMap<>(channels.size());
|
||||
for (String key : channels.keySet()) {
|
||||
mChannels.put(key, channels.getParcelable(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildOverridePeopleLocked() {
|
||||
Bundle overridePeople = mRankingUpdate.getOverridePeople();
|
||||
mOverridePeople = new ArrayMap<>(overridePeople.size());
|
||||
for (String key : overridePeople.keySet()) {
|
||||
mOverridePeople.put(key, overridePeople.getStringArrayList(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildSnoozeCriteriaLocked() {
|
||||
Bundle snoozeCriteria = mRankingUpdate.getSnoozeCriteria();
|
||||
mSnoozeCriteria = new ArrayMap<>(snoozeCriteria.size());
|
||||
for (String key : snoozeCriteria.keySet()) {
|
||||
mSnoozeCriteria.put(key, snoozeCriteria.getParcelableArrayList(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildShowBadgeLocked() {
|
||||
mShowBadge = buildBooleanMapFromBundle(mRankingUpdate.getShowBadge());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildUserSentimentLocked() {
|
||||
mUserSentiment = buildIntMapFromBundle(mRankingUpdate.getUserSentiment());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildHiddenLocked() {
|
||||
mHidden = buildBooleanMapFromBundle(mRankingUpdate.getHidden());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildLastAudiblyAlertedLocked() {
|
||||
mLastAudiblyAlerted = buildLongMapFromBundle(mRankingUpdate.getLastAudiblyAlerted());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildNoisyLocked() {
|
||||
mNoisy = buildBooleanMapFromBundle(mRankingUpdate.getNoisy());
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildSmartActions() {
|
||||
Bundle smartActions = mRankingUpdate.getSmartActions();
|
||||
mSmartActions = new ArrayMap<>(smartActions.size());
|
||||
for (String key : smartActions.keySet()) {
|
||||
mSmartActions.put(key, smartActions.getParcelableArrayList(key));
|
||||
}
|
||||
}
|
||||
|
||||
// Locked by 'this'
|
||||
private void buildSmartReplies() {
|
||||
Bundle smartReplies = mRankingUpdate.getSmartReplies();
|
||||
mSmartReplies = new ArrayMap<>(smartReplies.size());
|
||||
for (String key : smartReplies.keySet()) {
|
||||
mSmartReplies.put(key, smartReplies.getCharSequenceArrayList(key));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------- Parcelable
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeParcelable(mRankingUpdate, flags);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<RankingMap> CREATOR = new Creator<RankingMap>() {
|
||||
@Override
|
||||
public RankingMap createFromParcel(Parcel source) {
|
||||
NotificationRankingUpdate rankingUpdate = source.readParcelable(null);
|
||||
return new RankingMap(rankingUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RankingMap[] newArray(int size) {
|
||||
return new RankingMap[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private final class MyHandler extends Handler {
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package android.service.notification;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -23,73 +22,18 @@ import android.os.Parcelable;
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationRankingUpdate implements Parcelable {
|
||||
// TODO: Support incremental updates.
|
||||
private final String[] mKeys;
|
||||
private final String[] mInterceptedKeys;
|
||||
private final Bundle mVisibilityOverrides;
|
||||
private final Bundle mSuppressedVisualEffects;
|
||||
private final int[] mImportance;
|
||||
private final Bundle mImportanceExplanation;
|
||||
private final Bundle mOverrideGroupKeys;
|
||||
private final Bundle mChannels;
|
||||
private final Bundle mOverridePeople;
|
||||
private final Bundle mSnoozeCriteria;
|
||||
private final Bundle mShowBadge;
|
||||
private final Bundle mUserSentiment;
|
||||
private final Bundle mHidden;
|
||||
private final Bundle mSmartActions;
|
||||
private final Bundle mSmartReplies;
|
||||
private final Bundle mLastAudiblyAlerted;
|
||||
private final Bundle mNoisy;
|
||||
private final boolean[] mCanBubble;
|
||||
private final NotificationListenerService.RankingMap mRankingMap;
|
||||
|
||||
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
|
||||
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
|
||||
int[] importance, Bundle explanation, Bundle overrideGroupKeys,
|
||||
Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
|
||||
Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
|
||||
Bundle smartReplies, Bundle lastAudiblyAlerted, Bundle noisy, boolean[] canBubble) {
|
||||
mKeys = keys;
|
||||
mInterceptedKeys = interceptedKeys;
|
||||
mVisibilityOverrides = visibilityOverrides;
|
||||
mSuppressedVisualEffects = suppressedVisualEffects;
|
||||
mImportance = importance;
|
||||
mImportanceExplanation = explanation;
|
||||
mOverrideGroupKeys = overrideGroupKeys;
|
||||
mChannels = channels;
|
||||
mOverridePeople = overridePeople;
|
||||
mSnoozeCriteria = snoozeCriteria;
|
||||
mShowBadge = showBadge;
|
||||
mUserSentiment = userSentiment;
|
||||
mHidden = hidden;
|
||||
mSmartActions = smartActions;
|
||||
mSmartReplies = smartReplies;
|
||||
mLastAudiblyAlerted = lastAudiblyAlerted;
|
||||
mNoisy = noisy;
|
||||
mCanBubble = canBubble;
|
||||
public NotificationRankingUpdate(NotificationListenerService.Ranking[] rankings) {
|
||||
mRankingMap = new NotificationListenerService.RankingMap(rankings);
|
||||
}
|
||||
|
||||
public NotificationRankingUpdate(Parcel in) {
|
||||
mKeys = in.readStringArray();
|
||||
mInterceptedKeys = in.readStringArray();
|
||||
mVisibilityOverrides = in.readBundle();
|
||||
mSuppressedVisualEffects = in.readBundle();
|
||||
mImportance = new int[mKeys.length];
|
||||
in.readIntArray(mImportance);
|
||||
mImportanceExplanation = in.readBundle();
|
||||
mOverrideGroupKeys = in.readBundle();
|
||||
mChannels = in.readBundle();
|
||||
mOverridePeople = in.readBundle();
|
||||
mSnoozeCriteria = in.readBundle();
|
||||
mShowBadge = in.readBundle();
|
||||
mUserSentiment = in.readBundle();
|
||||
mHidden = in.readBundle();
|
||||
mSmartActions = in.readBundle();
|
||||
mSmartReplies = in.readBundle();
|
||||
mLastAudiblyAlerted = in.readBundle();
|
||||
mNoisy = in.readBundle();
|
||||
mCanBubble = new boolean[mKeys.length];
|
||||
in.readBooleanArray(mCanBubble);
|
||||
mRankingMap = in.readParcelable(getClass().getClassLoader());
|
||||
}
|
||||
|
||||
public NotificationListenerService.RankingMap getRankingMap() {
|
||||
return mRankingMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,26 +41,18 @@ public class NotificationRankingUpdate implements Parcelable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
NotificationRankingUpdate other = (NotificationRankingUpdate) o;
|
||||
return mRankingMap.equals(other.mRankingMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeStringArray(mKeys);
|
||||
out.writeStringArray(mInterceptedKeys);
|
||||
out.writeBundle(mVisibilityOverrides);
|
||||
out.writeBundle(mSuppressedVisualEffects);
|
||||
out.writeIntArray(mImportance);
|
||||
out.writeBundle(mImportanceExplanation);
|
||||
out.writeBundle(mOverrideGroupKeys);
|
||||
out.writeBundle(mChannels);
|
||||
out.writeBundle(mOverridePeople);
|
||||
out.writeBundle(mSnoozeCriteria);
|
||||
out.writeBundle(mShowBadge);
|
||||
out.writeBundle(mUserSentiment);
|
||||
out.writeBundle(mHidden);
|
||||
out.writeBundle(mSmartActions);
|
||||
out.writeBundle(mSmartReplies);
|
||||
out.writeBundle(mLastAudiblyAlerted);
|
||||
out.writeBundle(mNoisy);
|
||||
out.writeBooleanArray(mCanBubble);
|
||||
out.writeParcelable(mRankingMap, flags);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<NotificationRankingUpdate> CREATOR
|
||||
@@ -129,76 +65,4 @@ public class NotificationRankingUpdate implements Parcelable {
|
||||
return new NotificationRankingUpdate[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String[] getOrderedKeys() {
|
||||
return mKeys;
|
||||
}
|
||||
|
||||
public String[] getInterceptedKeys() {
|
||||
return mInterceptedKeys;
|
||||
}
|
||||
|
||||
public Bundle getVisibilityOverrides() {
|
||||
return mVisibilityOverrides;
|
||||
}
|
||||
|
||||
public Bundle getSuppressedVisualEffects() {
|
||||
return mSuppressedVisualEffects;
|
||||
}
|
||||
|
||||
public int[] getImportance() {
|
||||
return mImportance;
|
||||
}
|
||||
|
||||
public Bundle getImportanceExplanation() {
|
||||
return mImportanceExplanation;
|
||||
}
|
||||
|
||||
public Bundle getOverrideGroupKeys() {
|
||||
return mOverrideGroupKeys;
|
||||
}
|
||||
|
||||
public Bundle getChannels() {
|
||||
return mChannels;
|
||||
}
|
||||
|
||||
public Bundle getOverridePeople() {
|
||||
return mOverridePeople;
|
||||
}
|
||||
|
||||
public Bundle getSnoozeCriteria() {
|
||||
return mSnoozeCriteria;
|
||||
}
|
||||
|
||||
public Bundle getShowBadge() {
|
||||
return mShowBadge;
|
||||
}
|
||||
|
||||
public Bundle getUserSentiment() {
|
||||
return mUserSentiment;
|
||||
}
|
||||
|
||||
public Bundle getHidden() {
|
||||
return mHidden;
|
||||
}
|
||||
|
||||
public Bundle getSmartActions() {
|
||||
return mSmartActions;
|
||||
}
|
||||
|
||||
public Bundle getSmartReplies() {
|
||||
return mSmartReplies;
|
||||
}
|
||||
|
||||
public Bundle getLastAudiblyAlerted() {
|
||||
return mLastAudiblyAlerted;
|
||||
}
|
||||
|
||||
public Bundle getNoisy() {
|
||||
return mNoisy;
|
||||
}
|
||||
|
||||
public boolean[] getCanBubble() {
|
||||
return mCanBubble;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7234,72 +7234,42 @@ public class NotificationManagerService extends SystemService {
|
||||
@GuardedBy("mNotificationLock")
|
||||
private NotificationRankingUpdate makeRankingUpdateLocked(ManagedServiceInfo info) {
|
||||
final int N = mNotificationList.size();
|
||||
ArrayList<String> keys = new ArrayList<String>(N);
|
||||
ArrayList<String> interceptedKeys = new ArrayList<String>(N);
|
||||
ArrayList<Integer> importance = new ArrayList<>(N);
|
||||
Bundle overrideGroupKeys = new Bundle();
|
||||
Bundle visibilityOverrides = new Bundle();
|
||||
Bundle suppressedVisualEffects = new Bundle();
|
||||
Bundle explanation = new Bundle();
|
||||
Bundle channels = new Bundle();
|
||||
Bundle overridePeople = new Bundle();
|
||||
Bundle snoozeCriteria = new Bundle();
|
||||
Bundle showBadge = new Bundle();
|
||||
Bundle userSentiment = new Bundle();
|
||||
Bundle hidden = new Bundle();
|
||||
Bundle systemGeneratedSmartActions = new Bundle();
|
||||
Bundle smartReplies = new Bundle();
|
||||
Bundle lastAudiblyAlerted = new Bundle();
|
||||
Bundle noisy = new Bundle();
|
||||
ArrayList<Boolean> canBubble = new ArrayList<>(N);
|
||||
final ArrayList<NotificationListenerService.Ranking> rankings = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
NotificationRecord record = mNotificationList.get(i);
|
||||
if (!isVisibleToListener(record.sbn, info)) {
|
||||
continue;
|
||||
}
|
||||
final String key = record.sbn.getKey();
|
||||
keys.add(key);
|
||||
importance.add(record.getImportance());
|
||||
if (record.getImportanceExplanation() != null) {
|
||||
explanation.putCharSequence(key, record.getImportanceExplanation());
|
||||
}
|
||||
if (record.isIntercepted()) {
|
||||
interceptedKeys.add(key);
|
||||
final NotificationListenerService.Ranking ranking =
|
||||
new NotificationListenerService.Ranking();
|
||||
ranking.populate(
|
||||
key,
|
||||
rankings.size(),
|
||||
!record.isIntercepted(),
|
||||
record.getPackageVisibilityOverride(),
|
||||
record.getSuppressedVisualEffects(),
|
||||
record.getImportance(),
|
||||
record.getImportanceExplanation(),
|
||||
record.sbn.getOverrideGroupKey(),
|
||||
record.getChannel(),
|
||||
record.getPeopleOverride(),
|
||||
record.getSnoozeCriteria(),
|
||||
record.canShowBadge(),
|
||||
record.getUserSentiment(),
|
||||
record.isHidden(),
|
||||
record.getLastAudiblyAlertedMs(),
|
||||
record.getSound() != null || record.getVibration() != null,
|
||||
record.getSystemGeneratedSmartActions(),
|
||||
record.getSmartReplies(),
|
||||
record.canBubble()
|
||||
);
|
||||
rankings.add(ranking);
|
||||
}
|
||||
|
||||
}
|
||||
suppressedVisualEffects.putInt(key, record.getSuppressedVisualEffects());
|
||||
if (record.getPackageVisibilityOverride()
|
||||
!= NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
|
||||
visibilityOverrides.putInt(key, record.getPackageVisibilityOverride());
|
||||
}
|
||||
overrideGroupKeys.putString(key, record.sbn.getOverrideGroupKey());
|
||||
channels.putParcelable(key, record.getChannel());
|
||||
overridePeople.putStringArrayList(key, record.getPeopleOverride());
|
||||
snoozeCriteria.putParcelableArrayList(key, record.getSnoozeCriteria());
|
||||
showBadge.putBoolean(key, record.canShowBadge());
|
||||
userSentiment.putInt(key, record.getUserSentiment());
|
||||
hidden.putBoolean(key, record.isHidden());
|
||||
systemGeneratedSmartActions.putParcelableArrayList(key,
|
||||
record.getSystemGeneratedSmartActions());
|
||||
smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
|
||||
lastAudiblyAlerted.putLong(key, record.getLastAudiblyAlertedMs());
|
||||
noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null);
|
||||
canBubble.add(record.canBubble());
|
||||
}
|
||||
final int M = keys.size();
|
||||
String[] keysAr = keys.toArray(new String[M]);
|
||||
String[] interceptedKeysAr = interceptedKeys.toArray(new String[interceptedKeys.size()]);
|
||||
int[] importanceAr = new int[M];
|
||||
boolean[] canBubbleAr = new boolean[M];
|
||||
for (int i = 0; i < M; i++) {
|
||||
importanceAr[i] = importance.get(i);
|
||||
canBubbleAr[i] = canBubble.get(i);
|
||||
}
|
||||
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
|
||||
suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
|
||||
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
|
||||
systemGeneratedSmartActions, smartReplies, lastAudiblyAlerted, noisy,
|
||||
canBubbleAr);
|
||||
return new NotificationRankingUpdate(
|
||||
rankings.toArray(new NotificationListenerService.Ranking[0]));
|
||||
}
|
||||
|
||||
boolean hasCompanionDevice(ManagedServiceInfo info) {
|
||||
|
||||
@@ -20,7 +20,9 @@ import static android.service.notification.NotificationListenerService.Ranking.U
|
||||
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
|
||||
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -33,10 +35,11 @@ import android.app.NotificationChannel;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.NotificationListenerService.Ranking;
|
||||
import android.service.notification.NotificationListenerService.RankingMap;
|
||||
import android.service.notification.NotificationRankingUpdate;
|
||||
import android.service.notification.SnoozeCriterion;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
@@ -55,8 +58,6 @@ import java.util.List;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
|
||||
private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
|
||||
|
||||
@Test
|
||||
public void testGetActiveNotifications_notNull() throws Exception {
|
||||
TestListenerService service = new TestListenerService();
|
||||
@@ -97,52 +98,144 @@ public class NotificationListenerServiceTest extends UiServiceTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private NotificationRankingUpdate generateUpdate() {
|
||||
List<String> interceptedKeys = new ArrayList<>();
|
||||
Bundle visibilityOverrides = new Bundle();
|
||||
Bundle overrideGroupKeys = new Bundle();
|
||||
Bundle suppressedVisualEffects = new Bundle();
|
||||
Bundle explanation = new Bundle();
|
||||
Bundle channels = new Bundle();
|
||||
Bundle overridePeople = new Bundle();
|
||||
Bundle snoozeCriteria = new Bundle();
|
||||
Bundle showBadge = new Bundle();
|
||||
int[] importance = new int[mKeys.length];
|
||||
Bundle userSentiment = new Bundle();
|
||||
Bundle mHidden = new Bundle();
|
||||
Bundle smartActions = new Bundle();
|
||||
Bundle smartReplies = new Bundle();
|
||||
Bundle lastAudiblyAlerted = new Bundle();
|
||||
Bundle noisy = new Bundle();
|
||||
boolean[] canBubble = new boolean[mKeys.length];
|
||||
// Tests parceling of NotificationRankingUpdate, and by extension, RankingMap and Ranking.
|
||||
@Test
|
||||
public void testRankingUpdate_parcel() {
|
||||
NotificationRankingUpdate nru = generateUpdate();
|
||||
Parcel parcel = Parcel.obtain();
|
||||
nru.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
NotificationRankingUpdate nru1 = NotificationRankingUpdate.CREATOR.createFromParcel(parcel);
|
||||
assertEquals(nru, nru1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mKeys.length; i++) {
|
||||
String key = mKeys[i];
|
||||
visibilityOverrides.putInt(key, getVisibilityOverride(i));
|
||||
overrideGroupKeys.putString(key, getOverrideGroupKey(key));
|
||||
if (isIntercepted(i)) {
|
||||
interceptedKeys.add(key);
|
||||
}
|
||||
suppressedVisualEffects.putInt(key, getSuppressedVisualEffects(i));
|
||||
importance[i] = getImportance(i);
|
||||
explanation.putString(key, getExplanation(key));
|
||||
channels.putParcelable(key, getChannel(key, i));
|
||||
overridePeople.putStringArrayList(key, getPeople(key, i));
|
||||
snoozeCriteria.putParcelableArrayList(key, getSnoozeCriteria(key, i));
|
||||
showBadge.putBoolean(key, getShowBadge(i));
|
||||
userSentiment.putInt(key, getUserSentiment(i));
|
||||
mHidden.putBoolean(key, getHidden(i));
|
||||
smartActions.putParcelableArrayList(key, getSmartActions(key, i));
|
||||
smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
|
||||
lastAudiblyAlerted.putLong(key, lastAudiblyAlerted(i));
|
||||
noisy.putBoolean(key, getNoisy(i));
|
||||
canBubble[i] = canBubble(i);
|
||||
private void detailedAssertEquals(RankingMap a, RankingMap b) {
|
||||
Ranking arank = new Ranking();
|
||||
Ranking brank = new Ranking();
|
||||
assertArrayEquals(a.getOrderedKeys(), b.getOrderedKeys());
|
||||
for (String key : a.getOrderedKeys()) {
|
||||
a.getRanking(key, arank);
|
||||
b.getRanking(key, brank);
|
||||
detailedAssertEquals("ranking for key <" + key + ">", arank, brank);
|
||||
}
|
||||
NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
|
||||
interceptedKeys.toArray(new String[0]), visibilityOverrides,
|
||||
suppressedVisualEffects, importance, explanation, overrideGroupKeys,
|
||||
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
|
||||
smartActions, smartReplies, lastAudiblyAlerted, noisy, canBubble);
|
||||
}
|
||||
|
||||
// Tests parceling of RankingMap and RankingMap.equals
|
||||
@Test
|
||||
public void testRankingMap_parcel() {
|
||||
RankingMap rmap = generateUpdate().getRankingMap();
|
||||
Parcel parcel = Parcel.obtain();
|
||||
rmap.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
RankingMap rmap1 = RankingMap.CREATOR.createFromParcel(parcel);
|
||||
|
||||
detailedAssertEquals(rmap, rmap1);
|
||||
assertEquals(rmap, rmap1);
|
||||
}
|
||||
|
||||
private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
|
||||
assertEquals(comment, a.getKey(), b.getKey());
|
||||
assertEquals(comment, a.getRank(), b.getRank());
|
||||
assertEquals(comment, a.matchesInterruptionFilter(), b.matchesInterruptionFilter());
|
||||
assertEquals(comment, a.getVisibilityOverride(), b.getVisibilityOverride());
|
||||
assertEquals(comment, a.getSuppressedVisualEffects(), b.getSuppressedVisualEffects());
|
||||
assertEquals(comment, a.getImportance(), b.getImportance());
|
||||
assertEquals(comment, a.getImportanceExplanation(), b.getImportanceExplanation());
|
||||
assertEquals(comment, a.getOverrideGroupKey(), b.getOverrideGroupKey());
|
||||
assertEquals(comment, a.getChannel(), b.getChannel());
|
||||
assertEquals(comment, a.getAdditionalPeople(), b.getAdditionalPeople());
|
||||
assertEquals(comment, a.getSnoozeCriteria(), b.getSnoozeCriteria());
|
||||
assertEquals(comment, a.canShowBadge(), b.canShowBadge());
|
||||
assertEquals(comment, a.getUserSentiment(), b.getUserSentiment());
|
||||
assertEquals(comment, a.isSuspended(), b.isSuspended());
|
||||
assertEquals(comment, a.getLastAudiblyAlertedMillis(), b.getLastAudiblyAlertedMillis());
|
||||
assertEquals(comment, a.isNoisy(), b.isNoisy());
|
||||
assertEquals(comment, a.getSmartReplies(), b.getSmartReplies());
|
||||
assertEquals(comment, a.canBubble(), b.canBubble());
|
||||
assertActionsEqual(a.getSmartActions(), b.getSmartActions());
|
||||
}
|
||||
|
||||
// Tests parceling of Ranking and Ranking.equals
|
||||
@Test
|
||||
public void testRanking_parcel() {
|
||||
Ranking ranking = generateUpdate().getRankingMap().getRawRankingObject(mKeys[0]);
|
||||
Parcel parcel = Parcel.obtain();
|
||||
ranking.writeToParcel(parcel, 0);
|
||||
parcel.setDataPosition(0);
|
||||
Ranking ranking1 = new Ranking(parcel);
|
||||
detailedAssertEquals("rankings differ: ", ranking, ranking1);
|
||||
assertEquals(ranking, ranking1);
|
||||
}
|
||||
|
||||
private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
|
||||
assertEquals(a.getRankingMap(), b.getRankingMap());
|
||||
}
|
||||
|
||||
// Tests NotificationRankingUpdate.equals(), and by extension, RankingMap and Ranking.
|
||||
@Test
|
||||
public void testRankingUpdate_equals() {
|
||||
NotificationRankingUpdate nru = generateUpdate();
|
||||
NotificationRankingUpdate nru2 = generateUpdate();
|
||||
detailedAssertEquals(nru, nru2);
|
||||
assertEquals(nru, nru2);
|
||||
Ranking tweak = nru2.getRankingMap().getRawRankingObject(mKeys[0]);
|
||||
tweak.populate(
|
||||
tweak.getKey(),
|
||||
tweak.getRank(),
|
||||
!tweak.matchesInterruptionFilter(), // note the inversion here!
|
||||
tweak.getVisibilityOverride(),
|
||||
tweak.getSuppressedVisualEffects(),
|
||||
tweak.getImportance(),
|
||||
tweak.getImportanceExplanation(),
|
||||
tweak.getOverrideGroupKey(),
|
||||
tweak.getChannel(),
|
||||
(ArrayList) tweak.getAdditionalPeople(),
|
||||
(ArrayList) tweak.getSnoozeCriteria(),
|
||||
tweak.canShowBadge(),
|
||||
tweak.getUserSentiment(),
|
||||
tweak.isSuspended(),
|
||||
tweak.getLastAudiblyAlertedMillis(),
|
||||
tweak.isNoisy(),
|
||||
(ArrayList) tweak.getSmartActions(),
|
||||
(ArrayList) tweak.getSmartReplies(),
|
||||
tweak.canBubble()
|
||||
);
|
||||
assertNotEquals(nru, nru2);
|
||||
}
|
||||
|
||||
// Test data
|
||||
|
||||
private String[] mKeys = new String[] { "key", "key1", "key2", "key3", "key4"};
|
||||
|
||||
private NotificationRankingUpdate generateUpdate() {
|
||||
Ranking[] rankings = new Ranking[mKeys.length];
|
||||
for (int i = 0; i < mKeys.length; i++) {
|
||||
final String key = mKeys[i];
|
||||
Ranking ranking = new Ranking();
|
||||
ranking.populate(
|
||||
key,
|
||||
i,
|
||||
!isIntercepted(i),
|
||||
getVisibilityOverride(i),
|
||||
getSuppressedVisualEffects(i),
|
||||
getImportance(i),
|
||||
getExplanation(key),
|
||||
getOverrideGroupKey(key),
|
||||
getChannel(key, i),
|
||||
getPeople(key, i),
|
||||
getSnoozeCriteria(key, i),
|
||||
getShowBadge(i),
|
||||
getUserSentiment(i),
|
||||
getHidden(i),
|
||||
lastAudiblyAlerted(i),
|
||||
getNoisy(i),
|
||||
getSmartActions(key, i),
|
||||
getSmartReplies(key, i),
|
||||
canBubble(i)
|
||||
);
|
||||
rankings[i] = ranking;
|
||||
}
|
||||
NotificationRankingUpdate update = new NotificationRankingUpdate(rankings);
|
||||
return update;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user