Loading core/java/android/app/Notification.java +14 −0 Original line number Original line Diff line number Diff line Loading @@ -1731,6 +1731,20 @@ public class Notification implements Parcelable return contentView != null || extras.getBoolean(Builder.EXTRA_REBUILD_CONTENT_VIEW); return contentView != null || extras.getBoolean(Builder.EXTRA_REBUILD_CONTENT_VIEW); } } /** * @hide */ public boolean isGroupSummary() { return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) != 0; } /** * @hide */ public boolean isGroupChild() { return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) == 0; } /** /** * Builder class for {@link Notification} objects. * Builder class for {@link Notification} objects. * * Loading packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +27 −38 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.database.ContentObserver; import android.database.ContentObserver; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.Uri; import android.os.Build; import android.os.Build; Loading Loading @@ -96,7 +95,8 @@ import static com.android.keyguard.KeyguardHostView.OnDismissAction; public abstract class BaseStatusBar extends SystemUI implements public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener, CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener, RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger { RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment { public static final String TAG = "StatusBar"; public static final String TAG = "StatusBar"; public static final boolean DEBUG = false; public static final boolean DEBUG = false; public static final boolean MULTIUSER_DEBUG = false; public static final boolean MULTIUSER_DEBUG = false; Loading Loading @@ -132,7 +132,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected H mHandler = createHandler(); protected H mHandler = createHandler(); // all notifications // all notifications protected NotificationData mNotificationData = new NotificationData(); protected NotificationData mNotificationData; protected NotificationStackScrollLayout mStackScroller; protected NotificationStackScrollLayout mStackScroller; // for heads up notifications // for heads up notifications Loading Loading @@ -201,6 +201,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected NotificationOverflowContainer mKeyguardIconOverflowContainer; protected NotificationOverflowContainer mKeyguardIconOverflowContainer; protected DismissView mDismissView; protected DismissView mDismissView; @Override // NotificationData.Environment public boolean isDeviceProvisioned() { public boolean isDeviceProvisioned() { return mDeviceProvisioned; return mDeviceProvisioned; } } Loading Loading @@ -304,10 +305,6 @@ public abstract class BaseStatusBar extends SystemUI implements @Override @Override public void run() { public void run() { for (StatusBarNotification sbn : notifications) { for (StatusBarNotification sbn : notifications) { if (shouldFilterOut(sbn.getNotification())) { if (DEBUG) Log.d(TAG, "Ignoring notification: " + sbn); continue; } addNotification(sbn, currentRanking); addNotification(sbn, currentRanking); } } } } Loading @@ -322,20 +319,8 @@ public abstract class BaseStatusBar extends SystemUI implements @Override @Override public void run() { public void run() { Notification n = sbn.getNotification(); Notification n = sbn.getNotification(); boolean isUpdate = mNotificationData.findByKey(sbn.getKey()) != null boolean isUpdate = mNotificationData.get(sbn.getKey()) != null || isHeadsUp(sbn.getKey()); || 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) { if (isUpdate) { updateNotification(sbn, rankingMap); updateNotification(sbn, rankingMap); } else { } else { Loading Loading @@ -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() { private void updateCurrentProfilesCache() { Loading @@ -391,6 +371,8 @@ public abstract class BaseStatusBar extends SystemUI implements mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); mDisplay = mWindowManager.getDefaultDisplay(); mDisplay = mWindowManager.getDefaultDisplay(); mNotificationData = new NotificationData(this); mDreamManager = IDreamManager.Stub.asInterface( mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); ServiceManager.checkService(DreamService.DREAM_SERVICE)); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); Loading Loading @@ -499,7 +481,8 @@ public abstract class BaseStatusBar extends SystemUI implements return mHeadsUpNotificationView != null && mHeadsUpNotificationView.isShowing(key); 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 thisUserId = mCurrentUserId; final int notificationUserId = n.getUserId(); final int notificationUserId = n.getUserId(); if (DEBUG && MULTIUSER_DEBUG) { if (DEBUG && MULTIUSER_DEBUG) { Loading Loading @@ -881,6 +864,16 @@ public abstract class BaseStatusBar extends SystemUI implements return mUsersAllowingPrivateNotifications.get(userHandle); 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) { public void onNotificationClear(StatusBarNotification notification) { try { try { mBarService.onNotificationClear( mBarService.onNotificationClear( Loading Loading @@ -1381,11 +1374,14 @@ public abstract class BaseStatusBar extends SystemUI implements protected void updateRowStates() { protected void updateRowStates() { int maxKeyguardNotifications = getMaxKeyguardNotifications(); int maxKeyguardNotifications = getMaxKeyguardNotifications(); mKeyguardIconOverflowContainer.getIconsView().removeAllViews(); mKeyguardIconOverflowContainer.getIconsView().removeAllViews(); final int N = mNotificationData.size(); ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications(); final int N = activeNotifications.size(); int visibleNotifications = 0; int visibleNotifications = 0; boolean onKeyguard = mState == StatusBarState.KEYGUARD; boolean onKeyguard = mState == StatusBarState.KEYGUARD; for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) { NotificationData.Entry entry = mNotificationData.get(i); NotificationData.Entry entry = activeNotifications.get(i); if (onKeyguard) { if (onKeyguard) { entry.row.setExpansionDisabled(true); entry.row.setExpansionDisabled(true); } else { } else { Loading Loading @@ -1461,7 +1457,7 @@ public abstract class BaseStatusBar extends SystemUI implements if (wasHeadsUp) { if (wasHeadsUp) { oldEntry = mHeadsUpNotificationView.getEntry(); oldEntry = mHeadsUpNotificationView.getEntry(); } else { } else { oldEntry = mNotificationData.findByKey(key); oldEntry = mNotificationData.get(key); } } if (oldEntry == null) { if (oldEntry == null) { return; return; Loading Loading @@ -1620,6 +1616,7 @@ public abstract class BaseStatusBar extends SystemUI implements notification.getNotification().tickerText); notification.getNotification().tickerText); oldEntry.icon.set(ic); oldEntry.icon.set(ic); inflateViews(oldEntry, mStackScroller, wasHeadsUp); inflateViews(oldEntry, mStackScroller, wasHeadsUp); mNotificationData.updateRanking(ranking); updateNotifications(); updateNotifications(); } } } } Loading @@ -1630,7 +1627,7 @@ public abstract class BaseStatusBar extends SystemUI implements updateNotificationVetoButton(oldEntry.row, notification); updateNotificationVetoButton(oldEntry.row, notification); // Is this for you? // Is this for you? boolean isForCurrentUser = notificationIsForCurrentProfiles(notification); boolean isForCurrentUser = isNotificationForCurrentProfiles(notification); if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you"); if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you"); // Restart the ticker if it's still running // Restart the ticker if it's still running Loading Loading @@ -1725,14 +1722,6 @@ public abstract class BaseStatusBar extends SystemUI implements return interrupt; 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() { public boolean inKeyguardRestrictedInputMode() { return KeyguardTouchDelegate.getInstance(mContext).isInputRestricted(); return KeyguardTouchDelegate.getInstance(mContext).isInputRestricted(); } } Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +136 −52 Original line number Original line Diff line number Diff line Loading @@ -20,18 +20,22 @@ import android.app.Notification; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.view.View; import android.view.View; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.Comparator; import java.util.Comparator; /** /** * The list of currently displaying notifications. * The list of currently displaying notifications. * * TODO: Rename to NotificationList. */ */ public class NotificationData { public class NotificationData { private final Environment mEnvironment; public static final class Entry { public static final class Entry { public String key; public String key; public StatusBarNotification notification; public StatusBarNotification notification; Loading @@ -44,7 +48,6 @@ public class NotificationData { public boolean autoRedacted; // whether the redacted notification was generated by us public boolean autoRedacted; // whether the redacted notification was generated by us public boolean legacy; // whether the notification has a legacy, dark background public boolean legacy; // whether the notification has a legacy, dark background public Entry() {} public Entry(StatusBarNotification n, StatusBarIconView ic) { public Entry(StatusBarNotification n, StatusBarIconView ic) { this.key = n.getKey(); this.key = n.getKey(); this.notification = n; this.notification = n; Loading @@ -58,12 +61,6 @@ public class NotificationData { return expandedBig; return expandedBig; } } public View getPublicContentView() { return expandedPublic; } 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() { public void setInterruption() { interruption = true; interruption = true; Loading @@ -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 RankingMap mRankingMap; private final Ranking mTmpRanking = new Ranking(); private final Ranking mTmpRanking = new Ranking(); private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { Loading Loading @@ -118,36 +117,37 @@ public class NotificationData { } } }; }; public int size() { public NotificationData(Environment environment) { return mEntries.size(); 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) { public Entry get(String key) { for (Entry e : mEntries) { return mEntries.get(key); if (e.key.equals(key)) { return e; } } return null; } } public void add(Entry entry, RankingMap ranking) { public void add(Entry entry, RankingMap ranking) { mEntries.add(entry); mEntries.put(entry.notification.getKey(), entry); updateRankingAndSort(ranking); updateRankingAndSort(ranking); } } public Entry remove(String key, RankingMap ranking) { public Entry remove(String key, RankingMap ranking) { Entry e = findByKey(key); Entry removed = mEntries.remove(key); if (e == null) { if (removed == null) return null; return null; } mEntries.remove(e); updateRankingAndSort(ranking); updateRankingAndSort(ranking); return e; return removed; } } public void updateRanking(RankingMap ranking) { public void updateRanking(RankingMap ranking) { Loading @@ -155,45 +155,79 @@ public class NotificationData { } } public boolean isAmbient(String key) { 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); mRankingMap.getRanking(key, mTmpRanking); return mTmpRanking.isAmbient(); return mTmpRanking.isAmbient(); } } return false; } private void updateRankingAndSort(RankingMap ranking) { private void updateRankingAndSort(RankingMap ranking) { if (ranking != null) { if (ranking != null) { mRankingMap = ranking; mRankingMap = ranking; } } Collections.sort(mEntries, mRankingComparator); filterAndSort(); } } /** // TODO: This should not be public. Instead the Environment should notify this class when * Return whether there are any visible items (i.e. items without an error). // anything changed, and this class should call back the UI so it updates itself. */ public void filterAndSort() { public boolean hasVisibleItems() { mSortedAndFiltered.clear(); for (Entry e : mEntries) { if (e.expanded != null) { // the view successfully inflated 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; return true; } } if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) { return true; } if (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET && mEnvironment.shouldHideSensitiveContents(sbn.getUserId())) { return true; } } return false; 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() { public boolean hasActiveClearableNotifications() { for (Entry e : mEntries) { for (Entry e : mSortedAndFiltered) { if (e.expanded != null) { // the view successfully inflated if (e.expanded != null) { // the view successfully inflated if (e.notification.isClearable()) { if (e.notification.isClearable()) { return true; return true; Loading @@ -202,4 +236,54 @@ public class NotificationData { } } return false; 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); } } } packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1346,7 +1346,7 @@ public class NotificationPanelView extends PanelView implements float factor = 1f; float factor = 1f; if (mNotificationStackScroller.getNotGoneChildCount() > 0) { if (mNotificationStackScroller.getNotGoneChildCount() > 0) { factor = 0.6f; factor = 0.6f; } else if (!mStatusBar.hasNotifications()) { } else if (!mStatusBar.hasActiveNotifications()) { factor = 0.4f; factor = 0.4f; } } mEmptyDragAmount = amount * factor; mEmptyDragAmount = amount * factor; Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +52 −103 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/app/Notification.java +14 −0 Original line number Original line Diff line number Diff line Loading @@ -1731,6 +1731,20 @@ public class Notification implements Parcelable return contentView != null || extras.getBoolean(Builder.EXTRA_REBUILD_CONTENT_VIEW); return contentView != null || extras.getBoolean(Builder.EXTRA_REBUILD_CONTENT_VIEW); } } /** * @hide */ public boolean isGroupSummary() { return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) != 0; } /** * @hide */ public boolean isGroupChild() { return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) == 0; } /** /** * Builder class for {@link Notification} objects. * Builder class for {@link Notification} objects. * * Loading
packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +27 −38 Original line number Original line Diff line number Diff line Loading @@ -36,7 +36,6 @@ import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.res.Configuration; import android.database.ContentObserver; import android.database.ContentObserver; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.net.Uri; import android.net.Uri; import android.os.Build; import android.os.Build; Loading Loading @@ -96,7 +95,8 @@ import static com.android.keyguard.KeyguardHostView.OnDismissAction; public abstract class BaseStatusBar extends SystemUI implements public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener, CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener, RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger { RecentsComponent.Callbacks, ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment { public static final String TAG = "StatusBar"; public static final String TAG = "StatusBar"; public static final boolean DEBUG = false; public static final boolean DEBUG = false; public static final boolean MULTIUSER_DEBUG = false; public static final boolean MULTIUSER_DEBUG = false; Loading Loading @@ -132,7 +132,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected H mHandler = createHandler(); protected H mHandler = createHandler(); // all notifications // all notifications protected NotificationData mNotificationData = new NotificationData(); protected NotificationData mNotificationData; protected NotificationStackScrollLayout mStackScroller; protected NotificationStackScrollLayout mStackScroller; // for heads up notifications // for heads up notifications Loading Loading @@ -201,6 +201,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected NotificationOverflowContainer mKeyguardIconOverflowContainer; protected NotificationOverflowContainer mKeyguardIconOverflowContainer; protected DismissView mDismissView; protected DismissView mDismissView; @Override // NotificationData.Environment public boolean isDeviceProvisioned() { public boolean isDeviceProvisioned() { return mDeviceProvisioned; return mDeviceProvisioned; } } Loading Loading @@ -304,10 +305,6 @@ public abstract class BaseStatusBar extends SystemUI implements @Override @Override public void run() { public void run() { for (StatusBarNotification sbn : notifications) { for (StatusBarNotification sbn : notifications) { if (shouldFilterOut(sbn.getNotification())) { if (DEBUG) Log.d(TAG, "Ignoring notification: " + sbn); continue; } addNotification(sbn, currentRanking); addNotification(sbn, currentRanking); } } } } Loading @@ -322,20 +319,8 @@ public abstract class BaseStatusBar extends SystemUI implements @Override @Override public void run() { public void run() { Notification n = sbn.getNotification(); Notification n = sbn.getNotification(); boolean isUpdate = mNotificationData.findByKey(sbn.getKey()) != null boolean isUpdate = mNotificationData.get(sbn.getKey()) != null || isHeadsUp(sbn.getKey()); || 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) { if (isUpdate) { updateNotification(sbn, rankingMap); updateNotification(sbn, rankingMap); } else { } else { Loading Loading @@ -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() { private void updateCurrentProfilesCache() { Loading @@ -391,6 +371,8 @@ public abstract class BaseStatusBar extends SystemUI implements mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); mDisplay = mWindowManager.getDefaultDisplay(); mDisplay = mWindowManager.getDefaultDisplay(); mNotificationData = new NotificationData(this); mDreamManager = IDreamManager.Stub.asInterface( mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.checkService(DreamService.DREAM_SERVICE)); ServiceManager.checkService(DreamService.DREAM_SERVICE)); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); Loading Loading @@ -499,7 +481,8 @@ public abstract class BaseStatusBar extends SystemUI implements return mHeadsUpNotificationView != null && mHeadsUpNotificationView.isShowing(key); 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 thisUserId = mCurrentUserId; final int notificationUserId = n.getUserId(); final int notificationUserId = n.getUserId(); if (DEBUG && MULTIUSER_DEBUG) { if (DEBUG && MULTIUSER_DEBUG) { Loading Loading @@ -881,6 +864,16 @@ public abstract class BaseStatusBar extends SystemUI implements return mUsersAllowingPrivateNotifications.get(userHandle); 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) { public void onNotificationClear(StatusBarNotification notification) { try { try { mBarService.onNotificationClear( mBarService.onNotificationClear( Loading Loading @@ -1381,11 +1374,14 @@ public abstract class BaseStatusBar extends SystemUI implements protected void updateRowStates() { protected void updateRowStates() { int maxKeyguardNotifications = getMaxKeyguardNotifications(); int maxKeyguardNotifications = getMaxKeyguardNotifications(); mKeyguardIconOverflowContainer.getIconsView().removeAllViews(); mKeyguardIconOverflowContainer.getIconsView().removeAllViews(); final int N = mNotificationData.size(); ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications(); final int N = activeNotifications.size(); int visibleNotifications = 0; int visibleNotifications = 0; boolean onKeyguard = mState == StatusBarState.KEYGUARD; boolean onKeyguard = mState == StatusBarState.KEYGUARD; for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) { NotificationData.Entry entry = mNotificationData.get(i); NotificationData.Entry entry = activeNotifications.get(i); if (onKeyguard) { if (onKeyguard) { entry.row.setExpansionDisabled(true); entry.row.setExpansionDisabled(true); } else { } else { Loading Loading @@ -1461,7 +1457,7 @@ public abstract class BaseStatusBar extends SystemUI implements if (wasHeadsUp) { if (wasHeadsUp) { oldEntry = mHeadsUpNotificationView.getEntry(); oldEntry = mHeadsUpNotificationView.getEntry(); } else { } else { oldEntry = mNotificationData.findByKey(key); oldEntry = mNotificationData.get(key); } } if (oldEntry == null) { if (oldEntry == null) { return; return; Loading Loading @@ -1620,6 +1616,7 @@ public abstract class BaseStatusBar extends SystemUI implements notification.getNotification().tickerText); notification.getNotification().tickerText); oldEntry.icon.set(ic); oldEntry.icon.set(ic); inflateViews(oldEntry, mStackScroller, wasHeadsUp); inflateViews(oldEntry, mStackScroller, wasHeadsUp); mNotificationData.updateRanking(ranking); updateNotifications(); updateNotifications(); } } } } Loading @@ -1630,7 +1627,7 @@ public abstract class BaseStatusBar extends SystemUI implements updateNotificationVetoButton(oldEntry.row, notification); updateNotificationVetoButton(oldEntry.row, notification); // Is this for you? // Is this for you? boolean isForCurrentUser = notificationIsForCurrentProfiles(notification); boolean isForCurrentUser = isNotificationForCurrentProfiles(notification); if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you"); if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you"); // Restart the ticker if it's still running // Restart the ticker if it's still running Loading Loading @@ -1725,14 +1722,6 @@ public abstract class BaseStatusBar extends SystemUI implements return interrupt; 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() { public boolean inKeyguardRestrictedInputMode() { return KeyguardTouchDelegate.getInstance(mContext).isInputRestricted(); return KeyguardTouchDelegate.getInstance(mContext).isInputRestricted(); } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +136 −52 Original line number Original line Diff line number Diff line Loading @@ -20,18 +20,22 @@ import android.app.Notification; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.NotificationListenerService.RankingMap; import android.service.notification.StatusBarNotification; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.view.View; import android.view.View; import java.io.PrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collections; import java.util.Collections; import java.util.Comparator; import java.util.Comparator; /** /** * The list of currently displaying notifications. * The list of currently displaying notifications. * * TODO: Rename to NotificationList. */ */ public class NotificationData { public class NotificationData { private final Environment mEnvironment; public static final class Entry { public static final class Entry { public String key; public String key; public StatusBarNotification notification; public StatusBarNotification notification; Loading @@ -44,7 +48,6 @@ public class NotificationData { public boolean autoRedacted; // whether the redacted notification was generated by us public boolean autoRedacted; // whether the redacted notification was generated by us public boolean legacy; // whether the notification has a legacy, dark background public boolean legacy; // whether the notification has a legacy, dark background public Entry() {} public Entry(StatusBarNotification n, StatusBarIconView ic) { public Entry(StatusBarNotification n, StatusBarIconView ic) { this.key = n.getKey(); this.key = n.getKey(); this.notification = n; this.notification = n; Loading @@ -58,12 +61,6 @@ public class NotificationData { return expandedBig; return expandedBig; } } public View getPublicContentView() { return expandedPublic; } 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() { public void setInterruption() { interruption = true; interruption = true; Loading @@ -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 RankingMap mRankingMap; private final Ranking mTmpRanking = new Ranking(); private final Ranking mTmpRanking = new Ranking(); private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { Loading Loading @@ -118,36 +117,37 @@ public class NotificationData { } } }; }; public int size() { public NotificationData(Environment environment) { return mEntries.size(); 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) { public Entry get(String key) { for (Entry e : mEntries) { return mEntries.get(key); if (e.key.equals(key)) { return e; } } return null; } } public void add(Entry entry, RankingMap ranking) { public void add(Entry entry, RankingMap ranking) { mEntries.add(entry); mEntries.put(entry.notification.getKey(), entry); updateRankingAndSort(ranking); updateRankingAndSort(ranking); } } public Entry remove(String key, RankingMap ranking) { public Entry remove(String key, RankingMap ranking) { Entry e = findByKey(key); Entry removed = mEntries.remove(key); if (e == null) { if (removed == null) return null; return null; } mEntries.remove(e); updateRankingAndSort(ranking); updateRankingAndSort(ranking); return e; return removed; } } public void updateRanking(RankingMap ranking) { public void updateRanking(RankingMap ranking) { Loading @@ -155,45 +155,79 @@ public class NotificationData { } } public boolean isAmbient(String key) { 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); mRankingMap.getRanking(key, mTmpRanking); return mTmpRanking.isAmbient(); return mTmpRanking.isAmbient(); } } return false; } private void updateRankingAndSort(RankingMap ranking) { private void updateRankingAndSort(RankingMap ranking) { if (ranking != null) { if (ranking != null) { mRankingMap = ranking; mRankingMap = ranking; } } Collections.sort(mEntries, mRankingComparator); filterAndSort(); } } /** // TODO: This should not be public. Instead the Environment should notify this class when * Return whether there are any visible items (i.e. items without an error). // anything changed, and this class should call back the UI so it updates itself. */ public void filterAndSort() { public boolean hasVisibleItems() { mSortedAndFiltered.clear(); for (Entry e : mEntries) { if (e.expanded != null) { // the view successfully inflated 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; return true; } } if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) { return true; } if (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET && mEnvironment.shouldHideSensitiveContents(sbn.getUserId())) { return true; } } return false; 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() { public boolean hasActiveClearableNotifications() { for (Entry e : mEntries) { for (Entry e : mSortedAndFiltered) { if (e.expanded != null) { // the view successfully inflated if (e.expanded != null) { // the view successfully inflated if (e.notification.isClearable()) { if (e.notification.isClearable()) { return true; return true; Loading @@ -202,4 +236,54 @@ public class NotificationData { } } return false; 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); } } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1346,7 +1346,7 @@ public class NotificationPanelView extends PanelView implements float factor = 1f; float factor = 1f; if (mNotificationStackScroller.getNotGoneChildCount() > 0) { if (mNotificationStackScroller.getNotGoneChildCount() > 0) { factor = 0.6f; factor = 0.6f; } else if (!mStatusBar.hasNotifications()) { } else if (!mStatusBar.hasActiveNotifications()) { factor = 0.4f; factor = 0.4f; } } mEmptyDragAmount = amount * factor; mEmptyDragAmount = amount * factor; Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +52 −103 File changed.Preview size limit exceeded, changes collapsed. Show changes