summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java65
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java188
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java155
4 files changed, 216 insertions, 194 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f8cdd40..8eca0ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -36,7 +36,6 @@ import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.graphics.Rect;
-import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
@@ -96,7 +95,8 @@ import static com.android.keyguard.KeyguardHostView.OnDismissAction;
public abstract class BaseStatusBar extends SystemUI implements
CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener,
- RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger {
+ RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger,
+ NotificationData.Environment {
public static final String TAG = "StatusBar";
public static final boolean DEBUG = false;
public static final boolean MULTIUSER_DEBUG = false;
@@ -132,7 +132,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected H mHandler = createHandler();
// all notifications
- protected NotificationData mNotificationData = new NotificationData();
+ protected NotificationData mNotificationData;
protected NotificationStackScrollLayout mStackScroller;
// for heads up notifications
@@ -201,6 +201,7 @@ public abstract class BaseStatusBar extends SystemUI implements
protected NotificationOverflowContainer mKeyguardIconOverflowContainer;
protected DismissView mDismissView;
+ @Override // NotificationData.Environment
public boolean isDeviceProvisioned() {
return mDeviceProvisioned;
}
@@ -304,10 +305,6 @@ public abstract class BaseStatusBar extends SystemUI implements
@Override
public void run() {
for (StatusBarNotification sbn : notifications) {
- if (shouldFilterOut(sbn.getNotification())) {
- if (DEBUG) Log.d(TAG, "Ignoring notification: " + sbn);
- continue;
- }
addNotification(sbn, currentRanking);
}
}
@@ -322,20 +319,8 @@ public abstract class BaseStatusBar extends SystemUI implements
@Override
public void run() {
Notification n = sbn.getNotification();
- boolean isUpdate = mNotificationData.findByKey(sbn.getKey()) != null
+ boolean isUpdate = mNotificationData.get(sbn.getKey()) != null
|| isHeadsUp(sbn.getKey());
- if (shouldFilterOut(n)) {
- if (DEBUG) Log.d(TAG, "Ignoring notification: " + sbn);
- // If this is an update, i.e. the notification existed
- // before but wasn't filtered out, remove the old
- // instance. Otherwise just update the ranking.
- if (isUpdate) {
- removeNotification(sbn.getKey(), rankingMap);
- } else {
- updateNotificationRanking(rankingMap);
- }
- return;
- }
if (isUpdate) {
updateNotification(sbn, rankingMap);
} else {
@@ -368,11 +353,6 @@ public abstract class BaseStatusBar extends SystemUI implements
});
}
- private boolean shouldFilterOut(Notification n) {
- // Don't accept group children.
- return n.getGroup() != null
- && (n.flags & Notification.FLAG_GROUP_SUMMARY) == 0;
- }
};
private void updateCurrentProfilesCache() {
@@ -391,6 +371,8 @@ public abstract class BaseStatusBar extends SystemUI implements
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
mDisplay = mWindowManager.getDefaultDisplay();
+ mNotificationData = new NotificationData(this);
+
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -499,7 +481,8 @@ public abstract class BaseStatusBar extends SystemUI implements
return mHeadsUpNotificationView != null && mHeadsUpNotificationView.isShowing(key);
}
- public boolean notificationIsForCurrentProfiles(StatusBarNotification n) {
+ @Override // NotificationData.Environment
+ public boolean isNotificationForCurrentProfiles(StatusBarNotification n) {
final int thisUserId = mCurrentUserId;
final int notificationUserId = n.getUserId();
if (DEBUG && MULTIUSER_DEBUG) {
@@ -881,6 +864,16 @@ public abstract class BaseStatusBar extends SystemUI implements
return mUsersAllowingPrivateNotifications.get(userHandle);
}
+ /**
+ * Returns true if we're on a secure lockscreen and the user wants to hide "sensitive"
+ * notification data. If so, private notifications should show their (possibly
+ * auto-generated) publicVersion, and secret notifications should be totally invisible.
+ */
+ @Override // NotificationData.Environment
+ public boolean shouldHideSensitiveContents(int userid) {
+ return isLockscreenPublicMode() && !userAllowsPrivateNotificationsInPublic(userid);
+ }
+
public void onNotificationClear(StatusBarNotification notification) {
try {
mBarService.onNotificationClear(
@@ -1381,11 +1374,14 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void updateRowStates() {
int maxKeyguardNotifications = getMaxKeyguardNotifications();
mKeyguardIconOverflowContainer.getIconsView().removeAllViews();
- final int N = mNotificationData.size();
+
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ final int N = activeNotifications.size();
+
int visibleNotifications = 0;
boolean onKeyguard = mState == StatusBarState.KEYGUARD;
for (int i = 0; i < N; i++) {
- NotificationData.Entry entry = mNotificationData.get(i);
+ NotificationData.Entry entry = activeNotifications.get(i);
if (onKeyguard) {
entry.row.setExpansionDisabled(true);
} else {
@@ -1461,7 +1457,7 @@ public abstract class BaseStatusBar extends SystemUI implements
if (wasHeadsUp) {
oldEntry = mHeadsUpNotificationView.getEntry();
} else {
- oldEntry = mNotificationData.findByKey(key);
+ oldEntry = mNotificationData.get(key);
}
if (oldEntry == null) {
return;
@@ -1620,6 +1616,7 @@ public abstract class BaseStatusBar extends SystemUI implements
notification.getNotification().tickerText);
oldEntry.icon.set(ic);
inflateViews(oldEntry, mStackScroller, wasHeadsUp);
+ mNotificationData.updateRanking(ranking);
updateNotifications();
}
}
@@ -1630,7 +1627,7 @@ public abstract class BaseStatusBar extends SystemUI implements
updateNotificationVetoButton(oldEntry.row, notification);
// Is this for you?
- boolean isForCurrentUser = notificationIsForCurrentProfiles(notification);
+ boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
// Restart the ticker if it's still running
@@ -1725,14 +1722,6 @@ public abstract class BaseStatusBar extends SystemUI implements
return interrupt;
}
- // Q: What kinds of notifications should show during setup?
- // A: Almost none! Only things coming from the system (package is "android") that also
- // have special "kind" tags marking them as relevant for setup (see below).
- protected boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
- return "android".equals(sbn.getPackageName())
- && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
- }
-
public boolean inKeyguardRestrictedInputMode() {
return KeyguardTouchDelegate.getInstance(mContext).isInputRestricted();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index a1ab7ec..7581cc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -20,18 +20,22 @@ import android.app.Notification;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
+import android.util.ArrayMap;
+import android.util.ArraySet;
import android.view.View;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* The list of currently displaying notifications.
- *
- * TODO: Rename to NotificationList.
*/
public class NotificationData {
+
+ private final Environment mEnvironment;
+
public static final class Entry {
public String key;
public StatusBarNotification notification;
@@ -44,7 +48,6 @@ public class NotificationData {
public boolean autoRedacted; // whether the redacted notification was generated by us
public boolean legacy; // whether the notification has a legacy, dark background
- public Entry() {}
public Entry(StatusBarNotification n, StatusBarIconView ic) {
this.key = n.getKey();
this.notification = n;
@@ -58,12 +61,6 @@ public class NotificationData {
return expandedBig;
}
public View getPublicContentView() { return expandedPublic; }
- /**
- * Set the flag indicating that this is being touched by the user.
- */
- public void setUserLocked(boolean userLocked) {
- row.setUserLocked(userLocked);
- }
public void setInterruption() {
interruption = true;
@@ -90,7 +87,9 @@ public class NotificationData {
}
}
- private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
+ private final ArrayMap<String, Entry> mEntries = new ArrayMap<>();
+ private final ArrayList<Entry> mSortedAndFiltered = new ArrayList<>();
+
private RankingMap mRankingMap;
private final Ranking mTmpRanking = new Ranking();
private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
@@ -118,36 +117,37 @@ public class NotificationData {
}
};
- public int size() {
- return mEntries.size();
+ public NotificationData(Environment environment) {
+ mEnvironment = environment;
}
- public Entry get(int i) {
- return mEntries.get(i);
+ /**
+ * Returns the sorted list of active notifications (depending on {@link Environment}
+ *
+ * <p>
+ * This call doesn't update the list of active notifications. Call {@link #filterAndSort()}
+ * when the environment changes.
+ * <p>
+ * Don't hold on to or modify the returned list.
+ */
+ public ArrayList<Entry> getActiveNotifications() {
+ return mSortedAndFiltered;
}
- public Entry findByKey(String key) {
- for (Entry e : mEntries) {
- if (e.key.equals(key)) {
- return e;
- }
- }
- return null;
+ public Entry get(String key) {
+ return mEntries.get(key);
}
public void add(Entry entry, RankingMap ranking) {
- mEntries.add(entry);
+ mEntries.put(entry.notification.getKey(), entry);
updateRankingAndSort(ranking);
}
public Entry remove(String key, RankingMap ranking) {
- Entry e = findByKey(key);
- if (e == null) {
- return null;
- }
- mEntries.remove(e);
+ Entry removed = mEntries.remove(key);
+ if (removed == null) return null;
updateRankingAndSort(ranking);
- return e;
+ return removed;
}
public void updateRanking(RankingMap ranking) {
@@ -155,45 +155,79 @@ public class NotificationData {
}
public boolean isAmbient(String key) {
- // TODO: Remove when switching to NotificationListener.
- if (mRankingMap == null) {
- for (Entry entry : mEntries) {
- if (key.equals(entry.key)) {
- return entry.notification.getNotification().priority ==
- Notification.PRIORITY_MIN;
- }
- }
- } else {
- mRankingMap.getRanking(key, mTmpRanking);
- return mTmpRanking.isAmbient();
- }
- return false;
+ mRankingMap.getRanking(key, mTmpRanking);
+ return mTmpRanking.isAmbient();
}
private void updateRankingAndSort(RankingMap ranking) {
if (ranking != null) {
mRankingMap = ranking;
}
- Collections.sort(mEntries, mRankingComparator);
+ filterAndSort();
}
- /**
- * Return whether there are any visible items (i.e. items without an error).
- */
- public boolean hasVisibleItems() {
- for (Entry e : mEntries) {
- if (e.expanded != null) { // the view successfully inflated
- return true;
+ // TODO: This should not be public. Instead the Environment should notify this class when
+ // anything changed, and this class should call back the UI so it updates itself.
+ public void filterAndSort() {
+ mSortedAndFiltered.clear();
+
+ ArraySet<String> groupsWithSummaries = null;
+ final int N = mEntries.size();
+ for (int i = 0; i < N; i++) {
+ Entry entry = mEntries.valueAt(i);
+ StatusBarNotification sbn = entry.notification;
+
+ if (shouldFilterOut(sbn)) {
+ continue;
+ }
+
+ if (sbn.getNotification().isGroupSummary()) {
+ if (groupsWithSummaries == null) {
+ groupsWithSummaries = new ArraySet<>();
+ }
+ groupsWithSummaries.add(sbn.getGroupKey());
+ }
+ mSortedAndFiltered.add(entry);
+ }
+
+ // Second pass: Filter out group children with summary.
+ if (groupsWithSummaries != null) {
+ final int M = mSortedAndFiltered.size();
+ for (int i = M - 1; i >= 0; i--) {
+ Entry ent = mSortedAndFiltered.get(i);
+ StatusBarNotification sbn = ent.notification;
+ if (sbn.getNotification().isGroupChild() &&
+ groupsWithSummaries.contains(sbn.getGroupKey())) {
+ mSortedAndFiltered.remove(i);
+ }
}
}
+
+ Collections.sort(mSortedAndFiltered, mRankingComparator);
+ }
+
+ private boolean shouldFilterOut(StatusBarNotification sbn) {
+ if (!(mEnvironment.isDeviceProvisioned() ||
+ showNotificationEvenIfUnprovisioned(sbn))) {
+ return true;
+ }
+
+ if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
+ return true;
+ }
+
+ if (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET &&
+ mEnvironment.shouldHideSensitiveContents(sbn.getUserId())) {
+ return true;
+ }
return false;
}
/**
- * Return whether there are any clearable items (that aren't errors).
+ * Return whether there are any clearable notifications (that aren't errors).
*/
- public boolean hasClearableItems() {
- for (Entry e : mEntries) {
+ public boolean hasActiveClearableNotifications() {
+ for (Entry e : mSortedAndFiltered) {
if (e.expanded != null) { // the view successfully inflated
if (e.notification.isClearable()) {
return true;
@@ -202,4 +236,54 @@ public class NotificationData {
}
return false;
}
+
+ // Q: What kinds of notifications should show during setup?
+ // A: Almost none! Only things coming from the system (package is "android") that also
+ // have special "kind" tags marking them as relevant for setup (see below).
+ public static boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
+ return "android".equals(sbn.getPackageName())
+ && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
+ }
+
+ public void dump(PrintWriter pw, String indent) {
+ int N = mSortedAndFiltered.size();
+ pw.print(indent);
+ pw.println("active notifications: " + N);
+ for (int i = 0; i < N; i++) {
+ NotificationData.Entry e = mSortedAndFiltered.get(i);
+ dumpEntry(pw, indent, i, e);
+ }
+
+ int M = mEntries.size();
+ pw.print(indent);
+ pw.println("inactive notifications: " + M);
+ for (int i = 0; i < M; i++) {
+ Entry entry = mEntries.valueAt(i);
+ if (!mSortedAndFiltered.contains(entry)) {
+ dumpEntry(pw, indent, i, entry);
+ }
+ }
+ }
+
+ private void dumpEntry(PrintWriter pw, String indent, int i, Entry e) {
+ pw.print(indent);
+ pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
+ StatusBarNotification n = e.notification;
+ pw.print(indent);
+ pw.println(" pkg=" + n.getPackageName() + " id=" + n.getId() + " score=" + n
+ .getScore());
+ pw.print(indent);
+ pw.println(" notification=" + n.getNotification());
+ pw.print(indent);
+ pw.println(" tickerText=\"" + n.getNotification().tickerText + "\"");
+ }
+
+ /**
+ * Provides access to keyguard state and user settings dependent data.
+ */
+ public interface Environment {
+ public boolean shouldHideSensitiveContents(int userId);
+ public boolean isDeviceProvisioned();
+ public boolean isNotificationForCurrentProfiles(StatusBarNotification sbn);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6644a6c..cccfb7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1346,7 +1346,7 @@ public class NotificationPanelView extends PanelView implements
float factor = 1f;
if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
factor = 0.6f;
- } else if (!mStatusBar.hasNotifications()) {
+ } else if (!mStatusBar.hasActiveNotifications()) {
factor = 0.4f;
}
mEmptyDragAmount = amount * factor;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 044f69c..20a4092 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -453,8 +453,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private Runnable mLaunchTransitionEndRunnable;
private boolean mLaunchTransitionFadingAway;
- private boolean mHasNotifications;
-
private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD
| ViewState.LOCATION_TOP_STACK_PEEKING
| ViewState.LOCATION_MAIN_AREA
@@ -498,9 +496,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// notifications.
// 3. Report newly visible and no-longer visible notifications.
// 4. Keep currently visible notifications for next report.
- int N = mNotificationData.size();
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ int N = activeNotifications.size();
for (int i = 0; i < N; i++) {
- Entry entry = mNotificationData.get(i);
+ Entry entry = activeNotifications.get(i);
String key = entry.notification.getKey();
boolean previouslyVisible = mCurrentlyVisibleNotifications.contains(key);
boolean currentlyVisible =
@@ -1314,7 +1313,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// Recalculate the position of the sliding windows and the titles.
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
- if (CLOSE_PANEL_WHEN_EMPTIED && mNotificationData.size() == 0
+ if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
&& !mNotificationPanel.isTracking()) {
if (mState == StatusBarState.SHADE) {
animateCollapsePanels();
@@ -1342,27 +1341,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void updateNotificationShade() {
if (mStackScroller == null) return;
- int N = mNotificationData.size();
-
- ArrayList<View> toShow = new ArrayList<View>();
-
- final boolean provisioned = isDeviceProvisioned();
- // If the device hasn't been through Setup, we only show system notifications
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
+ final int N = activeNotifications.size();
for (int i=0; i<N; i++) {
- Entry ent = mNotificationData.get(i);
- if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
-
- if (!notificationIsForCurrentProfiles(ent.notification)) continue;
+ Entry ent = activeNotifications.get(i);
+ int vis = ent.notification.getNotification().visibility;
+ // Display public version of the notification if we need to redact.
final boolean hideSensitive = shouldHideSensitiveContents(ent.notification.getUserId());
- final int vis = ent.notification.getNotification().visibility;
-
- // when isLockscreenPublicMode() we suppress VISIBILITY_SECRET notifications
- if (vis == Notification.VISIBILITY_SECRET && hideSensitive) {
- continue;
- }
-
- // when isLockscreenPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
boolean showingPublic = vis == Notification.VISIBILITY_PRIVATE && hideSensitive;
ent.row.setShowingPublic(showingPublic);
if (ent.autoRedacted && ent.legacy) {
@@ -1419,40 +1406,24 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
updateSpeedbump();
updateClearAll();
- mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup);
+ mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned() && mUserSetup);
mShadeUpdates.check();
}
private void updateClearAll() {
- boolean showDismissView = false;
- if (mState != StatusBarState.KEYGUARD) {
- for (int i = 0; i < mNotificationData.size(); i++) {
- Entry entry = mNotificationData.get(i);
- if (entry.row.getParent() == null) {
- // This view isn't even added, so the stack scroller doesn't
- // know about it. Ignore completely.
- continue;
- }
- if (entry.row.getVisibility() != View.GONE && entry.expanded != null
- && entry.notification.isClearable()) {
- showDismissView = true;
- break;
- }
- }
- }
+ boolean showDismissView =
+ mState != StatusBarState.KEYGUARD &&
+ mNotificationData.hasActiveClearableNotifications();
mStackScroller.updateDismissView(showDismissView);
}
private void updateSpeedbump() {
int speedbumpIndex = -1;
int currentIndex = 0;
- for (int i = 0; i < mNotificationData.size(); i++) {
- Entry entry = mNotificationData.get(i);
- if (entry.row.getParent() == null) {
- // This view isn't even added, so the stack scroller doesn't
- // know about it. Ignore completely.
- continue;
- }
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ final int N = activeNotifications.size();
+ for (int i = 0; i < N; i++) {
+ Entry entry = activeNotifications.get(i);
if (entry.row.getVisibility() != View.GONE &&
mNotificationData.isAmbient(entry.key)) {
speedbumpIndex = currentIndex;
@@ -1468,47 +1439,35 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// TODO: Move this into updateNotificationIcons()?
if (mNotificationIcons == null) return;
+ mNotificationData.filterAndSort();
+
updateNotificationShade();
updateNotificationIcons();
}
- /**
- * Returns true if we're on a secure lockscreen and the user wants to hide "sensitive"
- * notification data. If so, private notifications should show their (possibly
- * auto-generated) publicVersion, and secret notifications should be totally invisible.
- */
- private boolean shouldHideSensitiveContents(int userid) {
- return isLockscreenPublicMode() && !userAllowsPrivateNotificationsInPublic(userid);
- }
-
private void updateNotificationIcons() {
final LinearLayout.LayoutParams params
= new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
- int N = mNotificationData.size();
-
- if (DEBUG) {
- Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" +
- mNotificationIcons);
- }
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ final int N = activeNotifications.size();
+ ArrayList<StatusBarIconView> toShow = new ArrayList<>(N);
- ArrayList<View> toShow = new ArrayList<View>();
-
- final boolean provisioned = isDeviceProvisioned();
- // If the device hasn't been through Setup, we only show system notifications
- for (int i=0; i<N; i++) {
- Entry ent = mNotificationData.get(i);
- if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
- || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
- if (!notificationIsForCurrentProfiles(ent.notification)) continue;
- if (ent.notification.getNotification().visibility == Notification.VISIBILITY_SECRET
- && shouldHideSensitiveContents(ent.notification.getUserId())) {
- // in "public" mode (atop a secure keyguard), secret notifs are totally hidden
+ // Filter out notifications with low scores.
+ for (int i = 0; i < N; i++) {
+ Entry ent = activeNotifications.get(i);
+ if (ent.notification.getScore() < HIDE_ICONS_BELOW_SCORE &&
+ !NotificationData.showNotificationEvenIfUnprovisioned(ent.notification)) {
continue;
}
toShow.add(ent.icon);
}
+ if (DEBUG) {
+ Log.d(TAG, "refreshing icons: " + toShow.size() +
+ " notifications, mNotificationIcons=" + mNotificationIcons);
+ }
+
ArrayList<View> toRemove = new ArrayList<View>();
for (int i=0; i<mNotificationIcons.getChildCount(); i++) {
View child = mNotificationIcons.getChildAt(i);
@@ -1584,17 +1543,17 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override
protected void setAreThereNotifications() {
- final boolean any = mNotificationData.size() > 0;
-
- final boolean clearable = any && mNotificationData.hasClearableItems();
if (SPEW) {
- Log.d(TAG, "setAreThereNotifications: N=" + mNotificationData.size()
- + " any=" + any + " clearable=" + clearable);
+ final boolean clearable = hasActiveNotifications() &&
+ mNotificationData.hasActiveClearableNotifications();
+ Log.d(TAG, "setAreThereNotifications: N=" +
+ mNotificationData.getActiveNotifications().size() + " any=" +
+ hasActiveNotifications() + " clearable=" + clearable);
}
final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
- final boolean showDot = (any&&!areLightsOn());
+ final boolean showDot = hasActiveNotifications() && !areLightsOn();
if (showDot != (nlo.getAlpha() == 1.0f)) {
if (showDot) {
nlo.setAlpha(0f);
@@ -1616,20 +1575,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
findAndUpdateMediaNotifications();
updateCarrierLabelVisibility(false);
-
- // TODO: Multiuser handling!
- mHasNotifications = any;
}
public void findAndUpdateMediaNotifications() {
boolean metaDataChanged = false;
synchronized (mNotificationData) {
- final int N = mNotificationData.size();
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ final int N = activeNotifications.size();
Entry mediaNotification = null;
MediaController controller = null;
- for (int i=0; i<N; i++) {
- final Entry entry = mNotificationData.get(i);
+ for (int i = 0; i < N; i++) {
+ final Entry entry = activeNotifications.get(i);
if (isMediaNotification(entry)) {
final MediaSession.Token token = entry.notification.getNotification().extras
.getParcelable(Notification.EXTRA_MEDIA_SESSION);
@@ -1667,7 +1624,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final String pkg = aController.getPackageName();
for (int i = 0; i < N; i++) {
- final Entry entry = mNotificationData.get(i);
+ final Entry entry = activeNotifications.get(i);
if (entry.notification.getPackageName().equals(pkg)) {
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: found controller matching "
@@ -2602,7 +2559,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (!isDeviceProvisioned()) return;
// not for you
- if (!notificationIsForCurrentProfiles(n)) return;
+ if (!isNotificationForCurrentProfiles(n)) return;
// Show the ticker if one is requested. Also don't do this
// until status bar window is attached to the window manager,
@@ -2753,16 +2710,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (DUMPTRUCK) {
synchronized (mNotificationData) {
- int N = mNotificationData.size();
- pw.println(" notification icons: " + N);
- for (int i=0; i<N; i++) {
- NotificationData.Entry e = mNotificationData.get(i);
- pw.println(" [" + i + "] key=" + e.key + " icon=" + e.icon);
- StatusBarNotification n = e.notification;
- pw.println(" pkg=" + n.getPackageName() + " id=" + n.getId() + " score=" + n.getScore());
- pw.println(" notification=" + n.getNotification());
- pw.println(" tickerText=\"" + n.getNotification().tickerText + "\"");
- }
+ mNotificationData.dump(pw, " ");
}
int N = mStatusIcons.getChildCount();
@@ -3610,7 +3558,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
@Override
public boolean onDraggedDown(View startingChild) {
- if (mHasNotifications) {
+ if (hasActiveNotifications()) {
// We have notifications, go to locked shade.
goToLockedShade(startingChild);
@@ -3752,8 +3700,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
notifyUiVisibilityChanged(mSystemUiVisibility);
}
- public boolean hasNotifications() {
- return mHasNotifications;
+ public boolean hasActiveNotifications() {
+ return !mNotificationData.getActiveNotifications().isEmpty();
}
private final class ShadeUpdates {
@@ -3762,8 +3710,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void check() {
mNewVisibleNotifications.clear();
- for (int i = 0; i < mNotificationData.size(); i++) {
- final Entry entry = mNotificationData.get(i);
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ for (int i = 0; i < activeNotifications.size(); i++) {
+ final Entry entry = activeNotifications.get(i);
final boolean visible = entry.row != null
&& entry.row.getVisibility() == View.VISIBLE;
if (visible) {