RankingHelperpublic class RankingHelper extends Object implements RankingConfigCopyright (c) 2014, The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. |
Fields Summary |
---|
private static final String | TAG | private static final boolean | DEBUG | private static final int | XML_VERSION | private static final String | TAG_RANKING | private static final String | TAG_PACKAGE | private static final String | ATT_VERSION | private static final String | ATT_NAME | private static final String | ATT_UID | private static final String | ATT_PRIORITY | private static final String | ATT_VISIBILITY | private final NotificationSignalExtractor[] | mSignalExtractors | private final NotificationComparator | mPreliminaryComparator | private final GlobalSortKeyComparator | mFinalComparator | private final android.util.ArrayMap | mPackagePriorities | private final android.util.ArrayMap | mPackageVisibilities | private final android.util.ArrayMap | mProxyByGroupTmp | private final android.content.Context | mContext | private final android.os.Handler | mRankingHandler |
Constructors Summary |
---|
public RankingHelper(android.content.Context context, android.os.Handler rankingHandler, String[] extractorNames)
mContext = context;
mRankingHandler = rankingHandler;
mPackagePriorities = new ArrayMap<String, SparseIntArray>();
mPackageVisibilities = new ArrayMap<String, SparseIntArray>();
final int N = extractorNames.length;
mSignalExtractors = new NotificationSignalExtractor[N];
for (int i = 0; i < N; i++) {
try {
Class<?> extractorClass = mContext.getClassLoader().loadClass(extractorNames[i]);
NotificationSignalExtractor extractor =
(NotificationSignalExtractor) extractorClass.newInstance();
extractor.initialize(mContext);
extractor.setConfig(this);
mSignalExtractors[i] = extractor;
} catch (ClassNotFoundException e) {
Slog.w(TAG, "Couldn't find extractor " + extractorNames[i] + ".", e);
} catch (InstantiationException e) {
Slog.w(TAG, "Couldn't instantiate extractor " + extractorNames[i] + ".", e);
} catch (IllegalAccessException e) {
Slog.w(TAG, "Problem accessing extractor " + extractorNames[i] + ".", e);
}
}
mProxyByGroupTmp = new ArrayMap<String, NotificationRecord>();
|
Methods Summary |
---|
public void | dump(java.io.PrintWriter pw, java.lang.String prefix, NotificationManagerService.DumpFilter filter)
if (filter == null) {
final int N = mSignalExtractors.length;
pw.print(prefix);
pw.print("mSignalExtractors.length = ");
pw.println(N);
for (int i = 0; i < N; i++) {
pw.print(prefix);
pw.print(" ");
pw.println(mSignalExtractors[i]);
}
}
final int N = mPackagePriorities.size();
if (filter == null) {
pw.print(prefix);
pw.println("package priorities:");
}
for (int i = 0; i < N; i++) {
String name = mPackagePriorities.keyAt(i);
if (filter == null || filter.matches(name)) {
SparseIntArray priorityByUid = mPackagePriorities.get(name);
final int M = priorityByUid.size();
for (int j = 0; j < M; j++) {
int uid = priorityByUid.keyAt(j);
int priority = priorityByUid.get(uid);
pw.print(prefix);
pw.print(" ");
pw.print(name);
pw.print(" (");
pw.print(uid);
pw.print(") has priority: ");
pw.println(priority);
}
}
}
| public void | extractSignals(NotificationRecord r)
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
NotificationSignalExtractor extractor = mSignalExtractors[i];
try {
RankingReconsideration recon = extractor.process(r);
if (recon != null) {
Message m = Message.obtain(mRankingHandler,
NotificationManagerService.MESSAGE_RECONSIDER_RANKING, recon);
long delay = recon.getDelay(TimeUnit.MILLISECONDS);
mRankingHandler.sendMessageDelayed(m, delay);
}
} catch (Throwable t) {
Slog.w(TAG, "NotificationSignalExtractor failed.", t);
}
}
| public T | findExtractor(java.lang.Class extractorClass)
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
final NotificationSignalExtractor extractor = mSignalExtractors[i];
if (extractorClass.equals(extractor.getClass())) {
return (T) extractor;
}
}
return null;
| public int | getPackagePriority(java.lang.String packageName, int uid)
int priority = Notification.PRIORITY_DEFAULT;
SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
if (priorityByUid != null) {
priority = priorityByUid.get(uid, Notification.PRIORITY_DEFAULT);
}
return priority;
| public int | getPackageVisibilityOverride(java.lang.String packageName, int uid)
int visibility = NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE;
SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
if (visibilityByUid != null) {
visibility = visibilityByUid.get(uid,
NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
}
return visibility;
| public int | indexOf(java.util.ArrayList notificationList, NotificationRecord target)
return Collections.binarySearch(notificationList, target, mFinalComparator);
| public void | readXml(org.xmlpull.v1.XmlPullParser parser)
int type = parser.getEventType();
if (type != XmlPullParser.START_TAG) return;
String tag = parser.getName();
if (!TAG_RANKING.equals(tag)) return;
mPackagePriorities.clear();
final int version = safeInt(parser, ATT_VERSION, XML_VERSION);
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
return;
}
if (type == XmlPullParser.START_TAG) {
if (TAG_PACKAGE.equals(tag)) {
int uid = safeInt(parser, ATT_UID, UserHandle.USER_ALL);
int priority = safeInt(parser, ATT_PRIORITY, Notification.PRIORITY_DEFAULT);
int vis = safeInt(parser, ATT_VISIBILITY,
NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE);
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
if (priority != Notification.PRIORITY_DEFAULT) {
SparseIntArray priorityByUid = mPackagePriorities.get(name);
if (priorityByUid == null) {
priorityByUid = new SparseIntArray();
mPackagePriorities.put(name, priorityByUid);
}
priorityByUid.put(uid, priority);
}
if (vis != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
SparseIntArray visibilityByUid = mPackageVisibilities.get(name);
if (visibilityByUid == null) {
visibilityByUid = new SparseIntArray();
mPackageVisibilities.put(name, visibilityByUid);
}
visibilityByUid.put(uid, vis);
}
}
}
}
}
throw new IllegalStateException("Failed to reach END_DOCUMENT");
| private static int | safeInt(org.xmlpull.v1.XmlPullParser parser, java.lang.String att, int defValue)
final String val = parser.getAttributeValue(null, att);
return tryParseInt(val, defValue);
| public void | setPackagePriority(java.lang.String packageName, int uid, int priority)
if (priority == getPackagePriority(packageName, uid)) {
return;
}
SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
if (priorityByUid == null) {
priorityByUid = new SparseIntArray();
mPackagePriorities.put(packageName, priorityByUid);
}
priorityByUid.put(uid, priority);
updateConfig();
| public void | setPackageVisibilityOverride(java.lang.String packageName, int uid, int visibility)
if (visibility == getPackageVisibilityOverride(packageName, uid)) {
return;
}
SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
if (visibilityByUid == null) {
visibilityByUid = new SparseIntArray();
mPackageVisibilities.put(packageName, visibilityByUid);
}
visibilityByUid.put(uid, visibility);
updateConfig();
| public void | sort(java.util.ArrayList notificationList)
final int N = notificationList.size();
// clear global sort keys
for (int i = N - 1; i >= 0; i--) {
notificationList.get(i).setGlobalSortKey(null);
}
// rank each record individually
Collections.sort(notificationList, mPreliminaryComparator);
synchronized (mProxyByGroupTmp) {
// record individual ranking result and nominate proxies for each group
for (int i = N - 1; i >= 0; i--) {
final NotificationRecord record = notificationList.get(i);
record.setAuthoritativeRank(i);
final String groupKey = record.getGroupKey();
boolean isGroupSummary = record.getNotification().isGroupSummary();
if (isGroupSummary || !mProxyByGroupTmp.containsKey(groupKey)) {
mProxyByGroupTmp.put(groupKey, record);
}
}
// assign global sort key:
// is_recently_intrusive:group_rank:is_group_summary:group_sort_key:rank
for (int i = 0; i < N; i++) {
final NotificationRecord record = notificationList.get(i);
NotificationRecord groupProxy = mProxyByGroupTmp.get(record.getGroupKey());
String groupSortKey = record.getNotification().getSortKey();
// We need to make sure the developer provided group sort key (gsk) is handled
// correctly:
// gsk="" < gsk=non-null-string < gsk=null
//
// We enforce this by using different prefixes for these three cases.
String groupSortKeyPortion;
if (groupSortKey == null) {
groupSortKeyPortion = "nsk";
} else if (groupSortKey.equals("")) {
groupSortKeyPortion = "esk";
} else {
groupSortKeyPortion = "gsk=" + groupSortKey;
}
boolean isGroupSummary = record.getNotification().isGroupSummary();
record.setGlobalSortKey(
String.format("intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
record.isRecentlyIntrusive() ? '0" : '1",
groupProxy.getAuthoritativeRank(),
isGroupSummary ? '0" : '1",
groupSortKeyPortion,
record.getAuthoritativeRank()));
}
mProxyByGroupTmp.clear();
}
// Do a second ranking pass, using group proxies
Collections.sort(notificationList, mFinalComparator);
| private static int | tryParseInt(java.lang.String value, int defValue)
if (TextUtils.isEmpty(value)) return defValue;
try {
return Integer.valueOf(value);
} catch (NumberFormatException e) {
return defValue;
}
| private void | updateConfig()
final int N = mSignalExtractors.length;
for (int i = 0; i < N; i++) {
mSignalExtractors[i].setConfig(this);
}
mRankingHandler.sendEmptyMessage(NotificationManagerService.MESSAGE_RANKING_CONFIG_CHANGE);
| public void | writeXml(org.xmlpull.v1.XmlSerializer out)
out.startTag(null, TAG_RANKING);
out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
final Set<String> packageNames = new ArraySet<>(mPackagePriorities.size()
+ mPackageVisibilities.size());
packageNames.addAll(mPackagePriorities.keySet());
packageNames.addAll(mPackageVisibilities.keySet());
final Set<Integer> packageUids = new ArraySet<>();
for (String packageName : packageNames) {
packageUids.clear();
SparseIntArray priorityByUid = mPackagePriorities.get(packageName);
SparseIntArray visibilityByUid = mPackageVisibilities.get(packageName);
if (priorityByUid != null) {
final int M = priorityByUid.size();
for (int j = 0; j < M; j++) {
packageUids.add(priorityByUid.keyAt(j));
}
}
if (visibilityByUid != null) {
final int M = visibilityByUid.size();
for (int j = 0; j < M; j++) {
packageUids.add(visibilityByUid.keyAt(j));
}
}
for (Integer uid : packageUids) {
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATT_NAME, packageName);
if (priorityByUid != null) {
final int priority = priorityByUid.get(uid);
if (priority != Notification.PRIORITY_DEFAULT) {
out.attribute(null, ATT_PRIORITY, Integer.toString(priority));
}
}
if (visibilityByUid != null) {
final int visibility = visibilityByUid.get(uid);
if (visibility != NotificationListenerService.Ranking.VISIBILITY_NO_OVERRIDE) {
out.attribute(null, ATT_VISIBILITY, Integer.toString(visibility));
}
}
out.attribute(null, ATT_UID, Integer.toString(uid));
out.endTag(null, TAG_PACKAGE);
}
}
out.endTag(null, TAG_RANKING);
|
|