Loading packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +63 −71 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -77,11 +78,12 @@ import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SearchPanelView; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Locale; import static com.android.keyguard.KeyguardHostView.OnDismissAction; Loading Loading @@ -194,7 +196,7 @@ public abstract class BaseStatusBar extends SystemUI implements mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0); if (provisioned != mDeviceProvisioned) { mDeviceProvisioned = provisioned; updateNotificationIcons(); updateNotifications(); } final int mode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF); Loading @@ -209,7 +211,7 @@ public abstract class BaseStatusBar extends SystemUI implements // so we just dump our cache ... mUsersAllowingPrivateNotifications.clear(); // ... and refresh all the notifications updateNotificationIcons(); updateNotifications(); } }; Loading Loading @@ -280,11 +282,12 @@ public abstract class BaseStatusBar extends SystemUI implements public void onListenerConnected() { if (DEBUG) Log.d(TAG, "onListenerConnected"); final StatusBarNotification[] notifications = getActiveNotifications(); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { for (StatusBarNotification sbn : notifications) { addNotificationInternal(sbn); addNotificationInternal(sbn, currentRanking); } } }); Loading @@ -293,13 +296,14 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void onNotificationPosted(final StatusBarNotification sbn) { if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { if (mNotificationData.findByKey(sbn.getKey()) != null) { updateNotificationInternal(sbn); updateNotificationInternal(sbn, currentRanking); } else { addNotificationInternal(sbn); addNotificationInternal(sbn, currentRanking); } } }); Loading @@ -308,10 +312,24 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void onNotificationRemoved(final StatusBarNotification sbn) { if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { removeNotificationInternal(sbn.getKey()); removeNotificationInternal(sbn.getKey(), currentRanking); } }); } @Override public void onNotificationRankingUpdate() { if (DEBUG) Log.d(TAG, "onRankingUpdate"); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { mNotificationData.updateRanking(currentRanking); updateNotifications(); } }); } Loading Loading @@ -1113,19 +1131,13 @@ public abstract class BaseStatusBar extends SystemUI implements } } protected StatusBarNotification removeNotificationViews(String key) { NotificationData.Entry entry = mNotificationData.remove(key); protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) { NotificationData.Entry entry = mNotificationData.remove(key, ranking); if (entry == null) { Log.w(TAG, "removeNotification for unknown key: " + key); return null; } // Remove the expanded view. ViewGroup rowParent = (ViewGroup)entry.row.getParent(); if (rowParent != null) rowParent.removeView(entry.row); updateRowStates(); updateNotificationIcons(); updateSpeedBump(); updateNotifications(); return entry.notification; } Loading Loading @@ -1159,35 +1171,17 @@ public abstract class BaseStatusBar extends SystemUI implements return entry; } protected void addNotificationViews(NotificationData.Entry entry) { protected void addNotificationViews(Entry entry, Ranking ranking) { if (entry == null) { return; } // Add the expanded view and icon. int pos = mNotificationData.add(entry); if (DEBUG) { Log.d(TAG, "addNotificationViews: added at " + pos); } updateRowStates(); updateNotificationIcons(); updateSpeedBump(); mNotificationData.add(entry, ranking); updateNotifications(); } protected void updateSpeedBump() { int n = mNotificationData.size(); int speedBumpIndex = -1; for (int i = n-1; i >= 0; i--) { NotificationData.Entry entry = mNotificationData.get(i); if (entry.row.getVisibility() != View.GONE && speedBumpIndex == -1 && entry.row.isBelowSpeedBump() ) { speedBumpIndex = n - 1 - i; } } mStackScroller.updateSpeedBumpIndex(speedBumpIndex); } private void addNotificationViews(StatusBarNotification notification) { addNotificationViews(createNotificationViews(notification)); private void addNotificationViews(StatusBarNotification notification, Ranking ranking) { addNotificationViews(createNotificationViews(notification), ranking); } /** Loading @@ -1201,17 +1195,17 @@ public abstract class BaseStatusBar extends SystemUI implements protected void updateRowStates() { int maxKeyguardNotifications = getMaxKeyguardNotifications(); mKeyguardIconOverflowContainer.getIconsView().removeAllViews(); int n = mNotificationData.size(); final int N = mNotificationData.size(); int visibleNotifications = 0; boolean onKeyguard = mState == StatusBarState.KEYGUARD; for (int i = n-1; i >= 0; i--) { for (int i = 0; i < N; i++) { NotificationData.Entry entry = mNotificationData.get(i); if (onKeyguard) { entry.row.setExpansionDisabled(true); } else { entry.row.setExpansionDisabled(false); if (!entry.row.isUserLocked()) { boolean top = (i == n-1); boolean top = (i == 0); entry.row.setSystemExpanded(top); } } Loading @@ -1238,6 +1232,9 @@ public abstract class BaseStatusBar extends SystemUI implements } else { mKeyguardIconOverflowContainer.setVisibility(View.GONE); } // Move overflow container to last position. mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer, mStackScroller.getChildCount() - 1); } private boolean shouldShowOnKeyguard(StatusBarNotification sbn) { Loading @@ -1247,46 +1244,42 @@ public abstract class BaseStatusBar extends SystemUI implements protected void setZenMode(int mode) { if (!isDeviceProvisioned()) return; mZenMode = mode; updateNotificationIcons(); updateNotifications(); } protected abstract void haltTicker(); protected abstract void setAreThereNotifications(); protected abstract void updateNotificationIcons(); protected abstract void updateNotifications(); protected abstract void tick(StatusBarNotification n, boolean firstTime); protected abstract void updateExpandedViewPos(int expandedPosition); protected abstract boolean shouldDisableNavbarGestures(); protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) { return parent != null && parent.indexOfChild(entry.row) == 0; } @Override public void addNotification(StatusBarNotification notification) { if (!USE_NOTIFICATION_LISTENER) { addNotificationInternal(notification); addNotificationInternal(notification, null); } } public abstract void addNotificationInternal(StatusBarNotification notification); public abstract void addNotificationInternal(StatusBarNotification notification, Ranking ranking); @Override public void removeNotification(String key) { if (!USE_NOTIFICATION_LISTENER) { removeNotificationInternal(key); removeNotificationInternal(key, null); } } protected abstract void removeNotificationInternal(String key); protected abstract void removeNotificationInternal(String key, Ranking ranking); public void updateNotification(StatusBarNotification notification) { if (!USE_NOTIFICATION_LISTENER) { updateNotificationInternal(notification); updateNotificationInternal(notification, null); } } public void updateNotificationInternal(StatusBarNotification notification) { public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) { if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")"); final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey()); Loading Loading @@ -1358,18 +1351,12 @@ public abstract class BaseStatusBar extends SystemUI implements && oldPublicContentView.getPackage().equals(publicContentView.getPackage()) && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId()); ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); boolean orderUnchanged = notification.getNotification().when == oldNotification.getNotification().when && notification.getScore() == oldNotification.getScore(); // score now encompasses/supersedes isOngoing() boolean updateTicker = notification.getNotification().tickerText != null && !TextUtils.equals(notification.getNotification().tickerText, oldEntry.notification.getNotification().tickerText); boolean isTopAnyway = isTopNotification(rowParent, oldEntry); if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged && (orderUnchanged || isTopAnyway)) { if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged) { if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey()); oldEntry.notification = notification; try { Loading Loading @@ -1397,22 +1384,20 @@ public abstract class BaseStatusBar extends SystemUI implements handleNotificationError(notification, "Couldn't update icon: " + ic); return; } updateRowStates(); updateSpeedBump(); mNotificationData.updateRanking(ranking); updateNotifications(); } catch (RuntimeException e) { // It failed to add cleanly. Log, and remove the view from the panel. Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); removeNotificationViews(notification.getKey()); addNotificationViews(notification); removeNotificationViews(notification.getKey(), ranking); addNotificationViews(notification, ranking); } } else { if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey()); if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed")); if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed")); if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top")); removeNotificationViews(notification.getKey()); addNotificationViews(notification); // will also replace the heads up removeNotificationViews(notification.getKey(), ranking); addNotificationViews(notification, ranking); // will also replace the heads up final NotificationData.Entry newEntry = mNotificationData.findByKey( notification.getKey()); final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion(); Loading Loading @@ -1559,5 +1544,12 @@ public abstract class BaseStatusBar extends SystemUI implements mWindowManager.removeViewImmediate(mSearchPanelView); } mContext.unregisterReceiver(mBroadcastReceiver); if (USE_NOTIFICATION_LISTENER) { try { mNotificationListener.unregisterAsSystemService(); } catch (RemoteException e) { // Ignore. } } } } packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java +4 −4 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class InterceptedNotifications { for (int i = 0; i < n; i++) { final StatusBarNotification sbn = mIntercepted.valueAt(i); sbn.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false); mBar.addNotificationInternal(sbn); mBar.addNotificationInternal(sbn, null); } mIntercepted.clear(); updateSyntheticNotification(); Loading Loading @@ -88,7 +88,7 @@ public class InterceptedNotifications { private void updateSyntheticNotification() { if (mIntercepted.isEmpty()) { if (mSynKey != null) { mBar.removeNotificationInternal(mSynKey); mBar.removeNotificationInternal(mSynKey, null); mSynKey = null; } return; Loading @@ -107,9 +107,9 @@ public class InterceptedNotifications { mBar.getCurrentUserHandle()); if (mSynKey == null) { mSynKey = sbn.getKey(); mBar.addNotificationInternal(sbn); mBar.addNotificationInternal(sbn, null); } else { mBar.updateNotificationInternal(sbn); mBar.updateNotificationInternal(sbn, null); } final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey); entry.row.setOnClickListener(mSynClickListener); Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +49 −20 Original line number Diff line number Diff line Loading @@ -16,15 +16,19 @@ package com.android.systemui.statusbar; import android.app.Notification; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.StatusBarNotification; import android.view.View; import android.widget.ImageView; 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 { public static final class Entry { Loading @@ -34,7 +38,6 @@ public class NotificationData { public ExpandableNotificationRow row; // the outer expanded view public View expanded; // the inflated RemoteViews public View expandedPublic; // for insecure lockscreens public ImageView largeIcon; public View expandedBig; private boolean interruption; public Entry() {} Loading Loading @@ -64,18 +67,23 @@ public class NotificationData { } private final ArrayList<Entry> mEntries = new ArrayList<Entry>(); private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() { // sort first by score, then by when private Ranking mRanking; private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { @Override public int compare(Entry a, Entry b) { if (mRanking != null) { return mRanking.getRank(a.key) - mRanking.getRank(b.key); } final StatusBarNotification na = a.notification; final StatusBarNotification nb = b.notification; int d = na.getScore() - nb.getScore(); int d = nb.getScore() - na.getScore(); if (a.interruption != b.interruption) { return a.interruption ? 1 : -1; return a.interruption ? -1 : 1; } else if (d != 0) { return d; } else { return (int) (na.getNotification().when - nb.getNotification().when); return (int) (nb.getNotification().when - na.getNotification().when); } } }; Loading @@ -97,26 +105,47 @@ public class NotificationData { return null; } public int add(Entry entry) { int i; int N = mEntries.size(); for (i = 0; i < N; i++) { if (mEntryCmp.compare(mEntries.get(i), entry) > 0) { break; } } mEntries.add(i, entry); return i; public void add(Entry entry, Ranking ranking) { mEntries.add(entry); updateRankingAndSort(ranking); } public Entry remove(String key) { public Entry remove(String key, Ranking ranking) { Entry e = findByKey(key); if (e != null) { mEntries.remove(e); if (e == null) { return null; } mEntries.remove(e); updateRankingAndSort(ranking); return e; } public void updateRanking(Ranking ranking) { updateRankingAndSort(ranking); } public boolean isAmbient(String key) { // TODO: Remove when switching to NotificationListener. if (mRanking == null) { for (Entry entry : mEntries) { if (key.equals(entry.key)) { return entry.notification.getNotification().priority == Notification.PRIORITY_MIN; } } } else { return mRanking.isAmbient(key); } return false; } private void updateRankingAndSort(Ranking ranking) { if (ranking != null) { mRanking = ranking; } Collections.sort(mEntries, mRankingComparator); } /** * Return whether there are any visible items (i.e. items without an error). */ Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +65 −15 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.DisplayMetrics; Loading Loading @@ -1037,13 +1038,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override public void addNotificationInternal(StatusBarNotification notification) { public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) { if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore()); Entry shadeEntry = createNotificationViews(notification); if (shadeEntry == null) { return; } if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification)) { // Forward the ranking so we can sort the new notification. mNotificationData.updateRanking(ranking); return; } if (mUseHeadsUp && shouldInterrupt(notification)) { Loading Loading @@ -1083,7 +1086,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, tick(notification, true); } } addNotificationViews(shadeEntry); addNotificationViews(shadeEntry, ranking); // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); updateExpandedViewPos(EXPANDED_LEAVE_ALONE); Loading @@ -1105,8 +1108,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override public void removeNotificationInternal(String key) { StatusBarNotification old = removeNotificationViews(key); public void removeNotificationInternal(String key, Ranking ranking) { StatusBarNotification old = removeNotificationViews(key, ranking); if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old); if (old != null) { Loading Loading @@ -1143,7 +1146,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, R.integer.config_show_search_delay); } private void loadNotificationShade() { private void updateNotificationShade() { if (mStackScroller == null) return; int N = mNotificationData.size(); Loading @@ -1153,7 +1156,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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(N-i-1); Entry ent = mNotificationData.get(i); if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue; // TODO How do we want to badge notifcations from profiles. Loading Loading @@ -1184,26 +1187,75 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, for (int i=0; i<toShow.size(); i++) { View v = toShow.get(i); if (v.getParent() == null) { mStackScroller.addView(v, i); mStackScroller.addView(v); } } // So after all this work notifications still aren't sorted correctly. // Let's do that now by advancing through toShow and mStackScroller in // lock-step, making sure mStackScroller matches what we see in toShow. int j = 0; for (int i = 0; i < mStackScroller.getChildCount(); i++) { View child = mStackScroller.getChildAt(i); if (!(child instanceof ExpandableNotificationRow)) { // We don't care about non-notification views. continue; } if (child == toShow.get(j)) { // Everything is well, advance both lists. j++; continue; } // Oops, wrong notification at this position. Put the right one // here and advance both lists. mStackScroller.changeViewPosition(toShow.get(j), i); j++; } updateRowStates(); updateSpeedbump(); mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup); } 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; } if (entry.row.getVisibility() != View.GONE && mNotificationData.isAmbient(entry.key)) { speedbumpIndex = currentIndex; break; } currentIndex++; } mStackScroller.updateSpeedBumpIndex(speedbumpIndex); } @Override protected void updateNotificationIcons() { protected void updateNotifications() { // TODO: Move this into updateNotificationIcons()? if (mNotificationIcons == null) return; loadNotificationShade(); updateNotificationShade(); updateNotificationIcons(); } 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); Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons); } ArrayList<View> toShow = new ArrayList<View>(); Loading @@ -1211,7 +1263,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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(N-i-1); Entry ent = mNotificationData.get(i); if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE) || showNotificationEvenIfUnprovisioned(ent.notification))) continue; if (!notificationIsForCurrentProfiles(ent.notification)) continue; Loading Loading @@ -2388,7 +2440,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void userSwitched(int newUserId) { if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); animateCollapsePanels(); updateNotificationIcons(); updateNotifications(); resetUserSetupObserver(); } Loading Loading @@ -2793,10 +2845,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateStackScrollerState(); updatePublicMode(); updateRowStates(); updateSpeedBump(); updateNotifications(); checkBarModes(); updateNotificationIcons(); updateCarrierLabelVisibility(false); } Loading packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +4 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +63 −71 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; import android.service.notification.NotificationListenerService; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -77,11 +78,12 @@ import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SearchPanelView; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.phone.KeyguardTouchDelegate; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Locale; import static com.android.keyguard.KeyguardHostView.OnDismissAction; Loading Loading @@ -194,7 +196,7 @@ public abstract class BaseStatusBar extends SystemUI implements mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0); if (provisioned != mDeviceProvisioned) { mDeviceProvisioned = provisioned; updateNotificationIcons(); updateNotifications(); } final int mode = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF); Loading @@ -209,7 +211,7 @@ public abstract class BaseStatusBar extends SystemUI implements // so we just dump our cache ... mUsersAllowingPrivateNotifications.clear(); // ... and refresh all the notifications updateNotificationIcons(); updateNotifications(); } }; Loading Loading @@ -280,11 +282,12 @@ public abstract class BaseStatusBar extends SystemUI implements public void onListenerConnected() { if (DEBUG) Log.d(TAG, "onListenerConnected"); final StatusBarNotification[] notifications = getActiveNotifications(); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { for (StatusBarNotification sbn : notifications) { addNotificationInternal(sbn); addNotificationInternal(sbn, currentRanking); } } }); Loading @@ -293,13 +296,14 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void onNotificationPosted(final StatusBarNotification sbn) { if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { if (mNotificationData.findByKey(sbn.getKey()) != null) { updateNotificationInternal(sbn); updateNotificationInternal(sbn, currentRanking); } else { addNotificationInternal(sbn); addNotificationInternal(sbn, currentRanking); } } }); Loading @@ -308,10 +312,24 @@ public abstract class BaseStatusBar extends SystemUI implements @Override public void onNotificationRemoved(final StatusBarNotification sbn) { if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { removeNotificationInternal(sbn.getKey()); removeNotificationInternal(sbn.getKey(), currentRanking); } }); } @Override public void onNotificationRankingUpdate() { if (DEBUG) Log.d(TAG, "onRankingUpdate"); final Ranking currentRanking = getCurrentRanking(); mHandler.post(new Runnable() { @Override public void run() { mNotificationData.updateRanking(currentRanking); updateNotifications(); } }); } Loading Loading @@ -1113,19 +1131,13 @@ public abstract class BaseStatusBar extends SystemUI implements } } protected StatusBarNotification removeNotificationViews(String key) { NotificationData.Entry entry = mNotificationData.remove(key); protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) { NotificationData.Entry entry = mNotificationData.remove(key, ranking); if (entry == null) { Log.w(TAG, "removeNotification for unknown key: " + key); return null; } // Remove the expanded view. ViewGroup rowParent = (ViewGroup)entry.row.getParent(); if (rowParent != null) rowParent.removeView(entry.row); updateRowStates(); updateNotificationIcons(); updateSpeedBump(); updateNotifications(); return entry.notification; } Loading Loading @@ -1159,35 +1171,17 @@ public abstract class BaseStatusBar extends SystemUI implements return entry; } protected void addNotificationViews(NotificationData.Entry entry) { protected void addNotificationViews(Entry entry, Ranking ranking) { if (entry == null) { return; } // Add the expanded view and icon. int pos = mNotificationData.add(entry); if (DEBUG) { Log.d(TAG, "addNotificationViews: added at " + pos); } updateRowStates(); updateNotificationIcons(); updateSpeedBump(); mNotificationData.add(entry, ranking); updateNotifications(); } protected void updateSpeedBump() { int n = mNotificationData.size(); int speedBumpIndex = -1; for (int i = n-1; i >= 0; i--) { NotificationData.Entry entry = mNotificationData.get(i); if (entry.row.getVisibility() != View.GONE && speedBumpIndex == -1 && entry.row.isBelowSpeedBump() ) { speedBumpIndex = n - 1 - i; } } mStackScroller.updateSpeedBumpIndex(speedBumpIndex); } private void addNotificationViews(StatusBarNotification notification) { addNotificationViews(createNotificationViews(notification)); private void addNotificationViews(StatusBarNotification notification, Ranking ranking) { addNotificationViews(createNotificationViews(notification), ranking); } /** Loading @@ -1201,17 +1195,17 @@ public abstract class BaseStatusBar extends SystemUI implements protected void updateRowStates() { int maxKeyguardNotifications = getMaxKeyguardNotifications(); mKeyguardIconOverflowContainer.getIconsView().removeAllViews(); int n = mNotificationData.size(); final int N = mNotificationData.size(); int visibleNotifications = 0; boolean onKeyguard = mState == StatusBarState.KEYGUARD; for (int i = n-1; i >= 0; i--) { for (int i = 0; i < N; i++) { NotificationData.Entry entry = mNotificationData.get(i); if (onKeyguard) { entry.row.setExpansionDisabled(true); } else { entry.row.setExpansionDisabled(false); if (!entry.row.isUserLocked()) { boolean top = (i == n-1); boolean top = (i == 0); entry.row.setSystemExpanded(top); } } Loading @@ -1238,6 +1232,9 @@ public abstract class BaseStatusBar extends SystemUI implements } else { mKeyguardIconOverflowContainer.setVisibility(View.GONE); } // Move overflow container to last position. mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer, mStackScroller.getChildCount() - 1); } private boolean shouldShowOnKeyguard(StatusBarNotification sbn) { Loading @@ -1247,46 +1244,42 @@ public abstract class BaseStatusBar extends SystemUI implements protected void setZenMode(int mode) { if (!isDeviceProvisioned()) return; mZenMode = mode; updateNotificationIcons(); updateNotifications(); } protected abstract void haltTicker(); protected abstract void setAreThereNotifications(); protected abstract void updateNotificationIcons(); protected abstract void updateNotifications(); protected abstract void tick(StatusBarNotification n, boolean firstTime); protected abstract void updateExpandedViewPos(int expandedPosition); protected abstract boolean shouldDisableNavbarGestures(); protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) { return parent != null && parent.indexOfChild(entry.row) == 0; } @Override public void addNotification(StatusBarNotification notification) { if (!USE_NOTIFICATION_LISTENER) { addNotificationInternal(notification); addNotificationInternal(notification, null); } } public abstract void addNotificationInternal(StatusBarNotification notification); public abstract void addNotificationInternal(StatusBarNotification notification, Ranking ranking); @Override public void removeNotification(String key) { if (!USE_NOTIFICATION_LISTENER) { removeNotificationInternal(key); removeNotificationInternal(key, null); } } protected abstract void removeNotificationInternal(String key); protected abstract void removeNotificationInternal(String key, Ranking ranking); public void updateNotification(StatusBarNotification notification) { if (!USE_NOTIFICATION_LISTENER) { updateNotificationInternal(notification); updateNotificationInternal(notification, null); } } public void updateNotificationInternal(StatusBarNotification notification) { public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) { if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")"); final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey()); Loading Loading @@ -1358,18 +1351,12 @@ public abstract class BaseStatusBar extends SystemUI implements && oldPublicContentView.getPackage().equals(publicContentView.getPackage()) && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId()); ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); boolean orderUnchanged = notification.getNotification().when == oldNotification.getNotification().when && notification.getScore() == oldNotification.getScore(); // score now encompasses/supersedes isOngoing() boolean updateTicker = notification.getNotification().tickerText != null && !TextUtils.equals(notification.getNotification().tickerText, oldEntry.notification.getNotification().tickerText); boolean isTopAnyway = isTopNotification(rowParent, oldEntry); if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged && (orderUnchanged || isTopAnyway)) { if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged) { if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey()); oldEntry.notification = notification; try { Loading Loading @@ -1397,22 +1384,20 @@ public abstract class BaseStatusBar extends SystemUI implements handleNotificationError(notification, "Couldn't update icon: " + ic); return; } updateRowStates(); updateSpeedBump(); mNotificationData.updateRanking(ranking); updateNotifications(); } catch (RuntimeException e) { // It failed to add cleanly. Log, and remove the view from the panel. Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); removeNotificationViews(notification.getKey()); addNotificationViews(notification); removeNotificationViews(notification.getKey(), ranking); addNotificationViews(notification, ranking); } } else { if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey()); if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed")); if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed")); if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top")); removeNotificationViews(notification.getKey()); addNotificationViews(notification); // will also replace the heads up removeNotificationViews(notification.getKey(), ranking); addNotificationViews(notification, ranking); // will also replace the heads up final NotificationData.Entry newEntry = mNotificationData.findByKey( notification.getKey()); final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion(); Loading Loading @@ -1559,5 +1544,12 @@ public abstract class BaseStatusBar extends SystemUI implements mWindowManager.removeViewImmediate(mSearchPanelView); } mContext.unregisterReceiver(mBroadcastReceiver); if (USE_NOTIFICATION_LISTENER) { try { mNotificationListener.unregisterAsSystemService(); } catch (RemoteException e) { // Ignore. } } } }
packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java +4 −4 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class InterceptedNotifications { for (int i = 0; i < n; i++) { final StatusBarNotification sbn = mIntercepted.valueAt(i); sbn.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false); mBar.addNotificationInternal(sbn); mBar.addNotificationInternal(sbn, null); } mIntercepted.clear(); updateSyntheticNotification(); Loading Loading @@ -88,7 +88,7 @@ public class InterceptedNotifications { private void updateSyntheticNotification() { if (mIntercepted.isEmpty()) { if (mSynKey != null) { mBar.removeNotificationInternal(mSynKey); mBar.removeNotificationInternal(mSynKey, null); mSynKey = null; } return; Loading @@ -107,9 +107,9 @@ public class InterceptedNotifications { mBar.getCurrentUserHandle()); if (mSynKey == null) { mSynKey = sbn.getKey(); mBar.addNotificationInternal(sbn); mBar.addNotificationInternal(sbn, null); } else { mBar.updateNotificationInternal(sbn); mBar.updateNotificationInternal(sbn, null); } final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey); entry.row.setOnClickListener(mSynClickListener); Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +49 −20 Original line number Diff line number Diff line Loading @@ -16,15 +16,19 @@ package com.android.systemui.statusbar; import android.app.Notification; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.StatusBarNotification; import android.view.View; import android.widget.ImageView; 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 { public static final class Entry { Loading @@ -34,7 +38,6 @@ public class NotificationData { public ExpandableNotificationRow row; // the outer expanded view public View expanded; // the inflated RemoteViews public View expandedPublic; // for insecure lockscreens public ImageView largeIcon; public View expandedBig; private boolean interruption; public Entry() {} Loading Loading @@ -64,18 +67,23 @@ public class NotificationData { } private final ArrayList<Entry> mEntries = new ArrayList<Entry>(); private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() { // sort first by score, then by when private Ranking mRanking; private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() { @Override public int compare(Entry a, Entry b) { if (mRanking != null) { return mRanking.getRank(a.key) - mRanking.getRank(b.key); } final StatusBarNotification na = a.notification; final StatusBarNotification nb = b.notification; int d = na.getScore() - nb.getScore(); int d = nb.getScore() - na.getScore(); if (a.interruption != b.interruption) { return a.interruption ? 1 : -1; return a.interruption ? -1 : 1; } else if (d != 0) { return d; } else { return (int) (na.getNotification().when - nb.getNotification().when); return (int) (nb.getNotification().when - na.getNotification().when); } } }; Loading @@ -97,26 +105,47 @@ public class NotificationData { return null; } public int add(Entry entry) { int i; int N = mEntries.size(); for (i = 0; i < N; i++) { if (mEntryCmp.compare(mEntries.get(i), entry) > 0) { break; } } mEntries.add(i, entry); return i; public void add(Entry entry, Ranking ranking) { mEntries.add(entry); updateRankingAndSort(ranking); } public Entry remove(String key) { public Entry remove(String key, Ranking ranking) { Entry e = findByKey(key); if (e != null) { mEntries.remove(e); if (e == null) { return null; } mEntries.remove(e); updateRankingAndSort(ranking); return e; } public void updateRanking(Ranking ranking) { updateRankingAndSort(ranking); } public boolean isAmbient(String key) { // TODO: Remove when switching to NotificationListener. if (mRanking == null) { for (Entry entry : mEntries) { if (key.equals(entry.key)) { return entry.notification.getNotification().priority == Notification.PRIORITY_MIN; } } } else { return mRanking.isAmbient(key); } return false; } private void updateRankingAndSort(Ranking ranking) { if (ranking != null) { mRanking = ranking; } Collections.sort(mEntries, mRankingComparator); } /** * Return whether there are any visible items (i.e. items without an error). */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +65 −15 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.Global; import android.service.notification.NotificationListenerService.Ranking; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.DisplayMetrics; Loading Loading @@ -1037,13 +1038,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override public void addNotificationInternal(StatusBarNotification notification) { public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) { if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore()); Entry shadeEntry = createNotificationViews(notification); if (shadeEntry == null) { return; } if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification)) { // Forward the ranking so we can sort the new notification. mNotificationData.updateRanking(ranking); return; } if (mUseHeadsUp && shouldInterrupt(notification)) { Loading Loading @@ -1083,7 +1086,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, tick(notification, true); } } addNotificationViews(shadeEntry); addNotificationViews(shadeEntry, ranking); // Recalculate the position of the sliding windows and the titles. setAreThereNotifications(); updateExpandedViewPos(EXPANDED_LEAVE_ALONE); Loading @@ -1105,8 +1108,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override public void removeNotificationInternal(String key) { StatusBarNotification old = removeNotificationViews(key); public void removeNotificationInternal(String key, Ranking ranking) { StatusBarNotification old = removeNotificationViews(key, ranking); if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old); if (old != null) { Loading Loading @@ -1143,7 +1146,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, R.integer.config_show_search_delay); } private void loadNotificationShade() { private void updateNotificationShade() { if (mStackScroller == null) return; int N = mNotificationData.size(); Loading @@ -1153,7 +1156,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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(N-i-1); Entry ent = mNotificationData.get(i); if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue; // TODO How do we want to badge notifcations from profiles. Loading Loading @@ -1184,26 +1187,75 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, for (int i=0; i<toShow.size(); i++) { View v = toShow.get(i); if (v.getParent() == null) { mStackScroller.addView(v, i); mStackScroller.addView(v); } } // So after all this work notifications still aren't sorted correctly. // Let's do that now by advancing through toShow and mStackScroller in // lock-step, making sure mStackScroller matches what we see in toShow. int j = 0; for (int i = 0; i < mStackScroller.getChildCount(); i++) { View child = mStackScroller.getChildAt(i); if (!(child instanceof ExpandableNotificationRow)) { // We don't care about non-notification views. continue; } if (child == toShow.get(j)) { // Everything is well, advance both lists. j++; continue; } // Oops, wrong notification at this position. Put the right one // here and advance both lists. mStackScroller.changeViewPosition(toShow.get(j), i); j++; } updateRowStates(); updateSpeedbump(); mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup); } 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; } if (entry.row.getVisibility() != View.GONE && mNotificationData.isAmbient(entry.key)) { speedbumpIndex = currentIndex; break; } currentIndex++; } mStackScroller.updateSpeedBumpIndex(speedbumpIndex); } @Override protected void updateNotificationIcons() { protected void updateNotifications() { // TODO: Move this into updateNotificationIcons()? if (mNotificationIcons == null) return; loadNotificationShade(); updateNotificationShade(); updateNotificationIcons(); } 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); Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons); } ArrayList<View> toShow = new ArrayList<View>(); Loading @@ -1211,7 +1263,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, 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(N-i-1); Entry ent = mNotificationData.get(i); if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE) || showNotificationEvenIfUnprovisioned(ent.notification))) continue; if (!notificationIsForCurrentProfiles(ent.notification)) continue; Loading Loading @@ -2388,7 +2440,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void userSwitched(int newUserId) { if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId); animateCollapsePanels(); updateNotificationIcons(); updateNotifications(); resetUserSetupObserver(); } Loading Loading @@ -2793,10 +2845,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, updateStackScrollerState(); updatePublicMode(); updateRowStates(); updateSpeedBump(); updateNotifications(); checkBarModes(); updateNotificationIcons(); updateCarrierLabelVisibility(false); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +4 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes