Skip to content

Commit 0c8275b

Browse files
committed
Pull up updateNotification to BaseStatusBar in preparation for modifying update behvior.
Bug: 6455789 Change-Id: I09fbf4d31643813cb4dfecaa496327d9625a15af
1 parent ca81b7d commit 0c8275b

File tree

4 files changed

+239
-438
lines changed

4 files changed

+239
-438
lines changed

packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import android.os.RemoteException;
3535
import android.os.ServiceManager;
3636
import android.provider.Settings;
37+
import android.text.TextUtils;
3738
import android.util.Log;
3839
import android.util.Slog;
3940
import android.view.Display;
@@ -46,6 +47,7 @@
4647
import android.view.ViewGroup.LayoutParams;
4748
import android.view.WindowManager;
4849
import android.view.WindowManagerImpl;
50+
import android.widget.ImageView;
4951
import android.widget.LinearLayout;
5052
import android.widget.RemoteViews;
5153
import android.widget.PopupMenu;
@@ -61,6 +63,7 @@
6163
import com.android.systemui.recent.RecentTasksLoader;
6264
import com.android.systemui.recent.TaskDescription;
6365
import com.android.systemui.statusbar.CommandQueue;
66+
import com.android.systemui.statusbar.policy.NotificationRowLayout;
6467
import com.android.systemui.statusbar.tablet.StatusBarPanel;
6568

6669
import com.android.systemui.R;
@@ -76,11 +79,24 @@ public abstract class BaseStatusBar extends SystemUI implements
7679
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
7780
protected static final int MSG_OPEN_SEARCH_PANEL = 1024;
7881
protected static final int MSG_CLOSE_SEARCH_PANEL = 1025;
82+
protected static final int MSG_SHOW_INTRUDER = 1026;
83+
protected static final int MSG_HIDE_INTRUDER = 1027;
84+
85+
protected static final boolean ENABLE_INTRUDERS = false;
86+
87+
public static final int EXPANDED_LEAVE_ALONE = -10000;
88+
public static final int EXPANDED_FULL_OPEN = -10001;
7989

8090
protected CommandQueue mCommandQueue;
8191
protected IStatusBarService mBarService;
8292
protected H mHandler = createHandler();
8393

94+
// all notifications
95+
protected NotificationData mNotificationData = new NotificationData();
96+
protected NotificationRowLayout mPile;
97+
98+
protected StatusBarNotification mCurrentlyIntrudingNotification;
99+
84100
// used to notify status bar for suppressing notification LED
85101
protected boolean mPanelSlightlyVisible;
86102

@@ -633,4 +649,190 @@ protected void visibilityChanged(boolean visible) {
633649
}
634650
}
635651

652+
/**
653+
* Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
654+
* about the failure.
655+
*
656+
* WARNING: this will call back into us. Don't hold any locks.
657+
*/
658+
void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
659+
removeNotification(key);
660+
try {
661+
mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message);
662+
} catch (RemoteException ex) {
663+
// The end is nigh.
664+
}
665+
}
666+
667+
protected StatusBarNotification removeNotificationViews(IBinder key) {
668+
NotificationData.Entry entry = mNotificationData.remove(key);
669+
if (entry == null) {
670+
Slog.w(TAG, "removeNotification for unknown key: " + key);
671+
return null;
672+
}
673+
// Remove the expanded view.
674+
ViewGroup rowParent = (ViewGroup)entry.row.getParent();
675+
if (rowParent != null) rowParent.removeView(entry.row);
676+
updateNotificationIcons();
677+
678+
return entry.notification;
679+
}
680+
681+
protected StatusBarIconView addNotificationViews(IBinder key,
682+
StatusBarNotification notification) {
683+
if (DEBUG) {
684+
Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification);
685+
}
686+
// Construct the icon.
687+
final StatusBarIconView iconView = new StatusBarIconView(mContext,
688+
notification.pkg + "/0x" + Integer.toHexString(notification.id),
689+
notification.notification);
690+
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
691+
692+
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
693+
notification.notification.icon,
694+
notification.notification.iconLevel,
695+
notification.notification.number,
696+
notification.notification.tickerText);
697+
if (!iconView.set(ic)) {
698+
handleNotificationError(key, notification, "Couldn't create icon: " + ic);
699+
return null;
700+
}
701+
// Construct the expanded view.
702+
NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView);
703+
if (!inflateViews(entry, mPile)) {
704+
handleNotificationError(key, notification, "Couldn't expand RemoteViews for: "
705+
+ notification);
706+
return null;
707+
}
708+
709+
// Add the expanded view and icon.
710+
int pos = mNotificationData.add(entry);
711+
if (DEBUG) {
712+
Slog.d(TAG, "addNotificationViews: added at " + pos);
713+
}
714+
updateNotificationIcons();
715+
716+
return iconView;
717+
}
718+
719+
protected abstract void haltTicker();
720+
protected abstract void setAreThereNotifications();
721+
protected abstract void updateNotificationIcons();
722+
protected abstract void tick(IBinder key, StatusBarNotification n, boolean firstTime);
723+
protected abstract void updateExpandedViewPos(int expandedPosition);
724+
725+
protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
726+
return parent.indexOfChild(entry.row) == 0;
727+
}
728+
729+
public void updateNotification(IBinder key, StatusBarNotification notification) {
730+
if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ")");
731+
732+
final NotificationData.Entry oldEntry = mNotificationData.findByKey(key);
733+
if (oldEntry == null) {
734+
Slog.w(TAG, "updateNotification for unknown key: " + key);
735+
return;
736+
}
737+
738+
final StatusBarNotification oldNotification = oldEntry.notification;
739+
740+
// XXX: modify when we do something more intelligent with the two content views
741+
final RemoteViews oldContentView = (oldNotification.notification.bigContentView != null)
742+
? oldNotification.notification.bigContentView
743+
: oldNotification.notification.contentView;
744+
final RemoteViews contentView = (notification.notification.bigContentView != null)
745+
? notification.notification.bigContentView
746+
: notification.notification.contentView;
747+
748+
if (DEBUG) {
749+
Slog.d(TAG, "old notification: when=" + oldNotification.notification.when
750+
+ " ongoing=" + oldNotification.isOngoing()
751+
+ " expanded=" + oldEntry.expanded
752+
+ " contentView=" + oldContentView
753+
+ " rowParent=" + oldEntry.row.getParent());
754+
Slog.d(TAG, "new notification: when=" + notification.notification.when
755+
+ " ongoing=" + oldNotification.isOngoing()
756+
+ " contentView=" + contentView);
757+
}
758+
759+
// Can we just reapply the RemoteViews in place? If when didn't change, the order
760+
// didn't change.
761+
boolean contentsUnchanged = oldEntry.expanded != null
762+
&& contentView != null && oldContentView != null
763+
&& contentView.getPackage() != null
764+
&& oldContentView.getPackage() != null
765+
&& oldContentView.getPackage().equals(contentView.getPackage())
766+
&& oldContentView.getLayoutId() == contentView.getLayoutId();
767+
ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
768+
boolean orderUnchanged = notification.notification.when==oldNotification.notification.when
769+
&& notification.score == oldNotification.score;
770+
// score now encompasses/supersedes isOngoing()
771+
772+
boolean updateTicker = notification.notification.tickerText != null
773+
&& !TextUtils.equals(notification.notification.tickerText,
774+
oldEntry.notification.notification.tickerText);
775+
boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
776+
if (contentsUnchanged && (orderUnchanged || isTopAnyway)) {
777+
if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key);
778+
oldEntry.notification = notification;
779+
try {
780+
// Reapply the RemoteViews
781+
contentView.reapply(mContext, oldEntry.content);
782+
// update the contentIntent
783+
final PendingIntent contentIntent = notification.notification.contentIntent;
784+
if (contentIntent != null) {
785+
final View.OnClickListener listener = makeClicker(contentIntent,
786+
notification.pkg, notification.tag, notification.id);
787+
oldEntry.content.setOnClickListener(listener);
788+
} else {
789+
oldEntry.content.setOnClickListener(null);
790+
}
791+
// Update the icon.
792+
final StatusBarIcon ic = new StatusBarIcon(notification.pkg,
793+
notification.notification.icon, notification.notification.iconLevel,
794+
notification.notification.number,
795+
notification.notification.tickerText);
796+
if (!oldEntry.icon.set(ic)) {
797+
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
798+
return;
799+
}
800+
}
801+
catch (RuntimeException e) {
802+
// It failed to add cleanly. Log, and remove the view from the panel.
803+
Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
804+
removeNotificationViews(key);
805+
addNotificationViews(key, notification);
806+
}
807+
} else {
808+
if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key);
809+
removeNotificationViews(key);
810+
addNotificationViews(key, notification);
811+
}
812+
813+
// Update the veto button accordingly (and as a result, whether this row is
814+
// swipe-dismissable)
815+
updateNotificationVetoButton(oldEntry.row, notification);
816+
817+
// Restart the ticker if it's still running
818+
if (updateTicker) {
819+
haltTicker();
820+
tick(key, notification, false);
821+
}
822+
823+
// Recalculate the position of the sliding windows and the titles.
824+
setAreThereNotifications();
825+
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
826+
827+
// See if we need to update the intruder.
828+
if (ENABLE_INTRUDERS && oldNotification == mCurrentlyIntrudingNotification) {
829+
if (DEBUG) Slog.d(TAG, "updating the current intruder:" + notification);
830+
// XXX: this is a hack for Alarms. The real implementation will need to *update*
831+
// the intruder.
832+
if (notification.notification.fullScreenIntent == null) { // TODO(dsandler): consistent logic with add()
833+
if (DEBUG) Slog.d(TAG, "no longer intrudes!");
834+
mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER);
835+
}
836+
}
837+
}
636838
}

0 commit comments

Comments
 (0)