updateNotifications works.
Change-Id: I924763a2d42ca1967719f3eb72c57d1cbb912dd7
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
index 8a48826..ae2cac2 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -38,6 +38,13 @@
this.iconLevel = iconLevel;
}
+ public StatusBarIcon(String iconPackage, int iconId, int iconLevel, int number) {
+ this.iconPackage = iconPackage;
+ this.iconId = iconId;
+ this.iconLevel = iconLevel;
+ this.number = number;
+ }
+
public String toString() {
return "StatusBarIcon(pkg=" + this.iconPackage + " id=0x" + Integer.toHexString(this.iconId)
+ " level=" + this.iconLevel + " visible=" + visible
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java
index b8d72fb..5499676 100644
--- a/core/java/com/android/internal/statusbar/StatusBarNotification.java
+++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java
@@ -103,7 +103,7 @@
}
public String toString() {
- return "StatusBarNotification(package=" + pkg + " tag=" + tag
+ return "StatusBarNotification(package=" + pkg + " id=" + id + " tag=" + tag
+ " notification=" + notification + ")";
}
diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java
index 5c7a90c..3c93021 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/NotificationData.java
@@ -30,8 +30,9 @@
public static final class Entry {
public IBinder key;
public StatusBarNotification notification;
- public View expanded;
public StatusBarIconView icon;
+ public View expanded; // the outer expanded view
+ public View contents; // the inflated RemoteViews
}
private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
@@ -43,6 +44,17 @@
return mEntries.get(index);
}
+ public int findEntry(IBinder key) {
+ final int N = mEntries.size();
+ for (int i=0; i<N; i++) {
+ Entry entry = mEntries.get(i);
+ if (entry.key == key) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
public int add(IBinder key, StatusBarNotification notification, View expanded,
StatusBarIconView icon) {
Entry entry = new Entry();
diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
index bd9ecb67..397dd47 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
@@ -297,10 +297,6 @@
WindowManagerImpl.getDefault().addView(view, lp);
}
- // ================================================================================
- // Always called from the UI thread.
- // ================================================================================
-
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex
+ " icon=" + icon);
@@ -323,6 +319,146 @@
}
public void addNotification(IBinder key, StatusBarNotification notification) {
+ addNotificationViews(key, notification);
+
+ // show the ticker
+ // TODO
+
+ // recalculate the position of the sliding windows
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+ }
+
+ public void updateNotification(IBinder key, StatusBarNotification notification) {
+ Slog.d(TAG, "updateNotification key=" + key + " notification=" + notification);
+
+ NotificationData oldList;
+ int oldIndex = mOngoing.findEntry(key);
+ if (oldIndex >= 0) {
+ oldList = mOngoing;
+ } else {
+ oldIndex = mLatest.findEntry(key);
+ if (oldIndex < 0) {
+ Slog.w(TAG, "updateNotification for unknown key: " + key);
+ return;
+ }
+ oldList = mLatest;
+ }
+ final NotificationData.Entry oldEntry = oldList.getEntryAt(oldIndex);
+ final StatusBarNotification oldNotification = oldEntry.notification;
+ final RemoteViews oldContentView = oldNotification.notification.contentView;
+
+ final RemoteViews contentView = notification.notification.contentView;
+
+ // Can we just reapply the RemoteViews in place? If when didn't change, the order
+ // didn't change.
+ if (notification.notification.when == oldNotification.notification.when
+ && notification.isOngoing() == oldNotification.isOngoing()
+ && oldEntry.contents != null
+ && contentView != null && oldContentView != null
+ && contentView.getPackage() != null
+ && oldContentView.getPackage() != null
+ && oldContentView.getPackage().equals(contentView.getPackage())
+ && oldContentView.getLayoutId() == contentView.getLayoutId()) {
+ Slog.d(TAG, "reusing notification");
+ oldEntry.notification = notification;
+ try {
+ // Reapply the RemoteViews
+ contentView.reapply(this, oldEntry.contents);
+ // update the contentIntent
+ ViewGroup clickView = (ViewGroup)oldEntry.expanded.findViewById(
+ com.android.internal.R.id.content);
+ final PendingIntent contentIntent = notification.notification.contentIntent;
+ if (contentIntent != null) {
+ clickView.setOnClickListener(new Launcher(contentIntent, notification.pkg,
+ notification.tag, notification.id));
+ }
+ }
+ catch (RuntimeException e) {
+ // It failed to add cleanly. Log, and remove the view from the panel.
+ Slog.w(TAG, "couldn't reapply views for package " + contentView.getPackage(), e);
+ removeNotificationViews(key);
+ addNotificationViews(key, notification);
+ }
+ // Update the icon.
+ oldEntry.icon.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
+ notification.notification.iconLevel, notification.notification.number));
+ } else {
+ Slog.d(TAG, "not reusing notification");
+ removeNotificationViews(key);
+ addNotificationViews(key, notification);
+ }
+
+ // Restart the ticker if it's still running
+ // TODO
+
+ // Recalculate the position of the sliding windows and the titles.
+ setAreThereNotifications();
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+ }
+
+ public void removeNotification(IBinder key) {
+ Slog.d(TAG, "removeNotification key=" + key);
+ removeNotificationViews(key);
+
+ // Cancel the ticker if it's still running
+ // TODO
+
+ // Recalculate the position of the sliding windows and the titles.
+ setAreThereNotifications();
+ updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
+ }
+
+ private int chooseIconIndex(boolean isOngoing, int index) {
+ final int ongoingSize = mOngoing.size();
+ final int latestSize = mLatest.size();
+ if (!isOngoing) {
+ index = mLatest.size() + index;
+ }
+ return (ongoingSize + latestSize) - index - 1;
+ }
+
+ View makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
+ Notification n = notification.notification;
+ RemoteViews remoteViews = n.contentView;
+ if (remoteViews == null) {
+ return null;
+ }
+
+ // create the row view
+ LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ View row = inflater.inflate(com.android.internal.R.layout.status_bar_latest_event,
+ parent, false);
+
+ // bind the click event to the content area
+ ViewGroup content = (ViewGroup)row.findViewById(com.android.internal.R.id.content);
+ content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ content.setOnFocusChangeListener(mFocusChangeListener);
+ PendingIntent contentIntent = n.contentIntent;
+ if (contentIntent != null) {
+ content.setOnClickListener(new Launcher(contentIntent, notification.pkg,
+ notification.tag, notification.id));
+ }
+
+ View child = null;
+ Exception exception = null;
+ try {
+ child = remoteViews.apply(this, content);
+ }
+ catch (RuntimeException e) {
+ exception = e;
+ }
+ if (child == null) {
+ Slog.e(TAG, "couldn't inflate view for package " + notification.pkg, exception);
+ return null;
+ }
+ content.addView(child);
+
+ row.setDrawingCacheEnabled(true);
+
+ return row;
+ }
+
+ void addNotificationViews(IBinder key, StatusBarNotification notification) {
NotificationData list;
ViewGroup parent;
final boolean isOngoing = notification.isOngoing();
@@ -339,7 +475,7 @@
StatusBarIconView iconView = new StatusBarIconView(this,
notification.pkg + "/" + notification.id);
iconView.set(new StatusBarIcon(notification.pkg, notification.notification.icon,
- notification.notification.iconLevel));
+ notification.notification.iconLevel, notification.notification.number));
// Add the expanded view.
final int viewIndex = list.add(key, notification, view, iconView);
parent.addView(view, viewIndex);
@@ -348,23 +484,14 @@
mNotificationIcons.addView(iconView, iconIndex,
new LinearLayout.LayoutParams(mIconWidth, mHeight));
- // show the ticker
- // TODO
-
- // recalculate the position of the sliding windows
- updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
}
- public void updateNotification(IBinder key, StatusBarNotification notification) {
- }
-
- public void removeNotification(IBinder key) {
- Slog.d(TAG, "removeNotification key=" + key);
+ void removeNotificationViews(IBinder key) {
NotificationData.Entry entry = mOngoing.remove(key);
if (entry == null) {
entry = mLatest.remove(key);
if (entry == null) {
- Slog.w(TAG, "removeNotification for nonexistent key: " + key);
+ Slog.w(TAG, "removeNotification for unknown key: " + key);
return;
}
}
@@ -372,15 +499,31 @@
((ViewGroup)entry.expanded.getParent()).removeView(entry.expanded);
// Remove the icon.
((ViewGroup)entry.icon.getParent()).removeView(entry.icon);
-
- // Cancel the ticker if it's still running
- // TODO
-
- // Recalculate the position of the sliding windows and the titles.
- setAreThereNotifications();
- updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
}
+ private void setAreThereNotifications() {
+ /*
+ boolean ongoing = mOngoingItems.getChildCount() != 0;
+ boolean latest = mLatestItems.getChildCount() != 0;
+
+ if (mNotificationData.hasClearableItems()) {
+ mClearButton.setVisibility(View.VISIBLE);
+ } else {
+ mClearButton.setVisibility(View.INVISIBLE);
+ }
+
+ mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
+ mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
+
+ if (ongoing || latest) {
+ mNoNotificationsTitle.setVisibility(View.GONE);
+ } else {
+ mNoNotificationsTitle.setVisibility(View.VISIBLE);
+ }
+ */
+ }
+
+
/**
* State is one or more of the DISABLE constants from StatusBarManager.
*/
@@ -441,158 +584,6 @@
}
};
- private int chooseIconIndex(boolean isOngoing, int index) {
- final int ongoingSize = mOngoing.size();
- final int latestSize = mLatest.size();
- if (!isOngoing) {
- index = mLatest.size() + index;
- }
- return (ongoingSize + latestSize) - index - 1;
- }
-
- View makeNotificationView(StatusBarNotification notification, ViewGroup parent) {
- Notification n = notification.notification;
- RemoteViews remoteViews = n.contentView;
- if (remoteViews == null) {
- return null;
- }
-
- // create the row view
- LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View row = inflater.inflate(com.android.internal.R.layout.status_bar_latest_event,
- parent, false);
-
- // bind the click event to the content area
- ViewGroup content = (ViewGroup)row.findViewById(com.android.internal.R.id.content);
- content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
- content.setOnFocusChangeListener(mFocusChangeListener);
- PendingIntent contentIntent = n.contentIntent;
- if (contentIntent != null) {
- content.setOnClickListener(new Launcher(contentIntent, notification.pkg,
- notification.tag, notification.id));
- }
-
- View child = null;
- Exception exception = null;
- try {
- child = remoteViews.apply(this, content);
- }
- catch (RuntimeException e) {
- exception = e;
- }
- if (child == null) {
- Slog.e(TAG, "couldn't inflate view for package " + notification.pkg, exception);
- return null;
- }
- content.addView(child);
-
- row.setDrawingCacheEnabled(true);
-
- /*
- notification.view = row;
- notification.contentView = child;
- */
-
- return row;
- }
-
- /*
- StatusBarIcon icon = new StatusBarIcon(pkg, notification.icon,
- notification.iconLevel);
- icon.number = notification.number;
- */
- /*
- void addNotificationView(StatusBarNotification notification) {
- if (notification.view != null) {
- throw new RuntimeException("Assertion failed: notification.view="
- + notification.view);
- }
-
- LinearLayout parent = notification.data.ongoingEvent ? mOngoingItems : mLatestItems;
-
- View child = makeNotificationView(notification, parent);
- if (child == null) {
- return ;
- }
-
- int index = mNotificationData.getExpandedIndex(notification);
- parent.addView(child, index);
- }
- */
-
- /**
- * Remove the old one and put the new one in its place.
- * @param notification the notification
- */
- /*
- void updateNotificationView(StatusBarNotification notification, NotificationData oldData) {
- NotificationData n = notification.data;
- if (oldData != null && n != null
- && n.when == oldData.when
- && n.ongoingEvent == oldData.ongoingEvent
- && n.contentView != null && oldData.contentView != null
- && n.contentView.getPackage() != null
- && oldData.contentView.getPackage() != null
- && oldData.contentView.getPackage().equals(n.contentView.getPackage())
- && oldData.contentView.getLayoutId() == n.contentView.getLayoutId()
- && notification.view != null) {
- mNotificationData.update(notification);
- try {
- n.contentView.reapply(this, notification.contentView);
-
- // update the contentIntent
- ViewGroup content = (ViewGroup)notification.view.findViewById(
- com.android.internal.R.id.content);
- PendingIntent contentIntent = n.contentIntent;
- if (contentIntent != null) {
- content.setOnClickListener(new Launcher(contentIntent, n.pkg, n.tag, n.id));
- }
- }
- catch (RuntimeException e) {
- // It failed to add cleanly. Log, and remove the view from the panel.
- Slog.w(TAG, "couldn't reapply views for package " + n.contentView.getPackage(), e);
- removeNotificationView(notification);
- }
- } else {
- mNotificationData.update(notification);
- removeNotificationView(notification);
- addNotificationView(notification);
- }
- setAreThereNotifications();
- }
-
- void removeNotificationView(StatusBarNotification notification) {
- View v = notification.view;
- if (v != null) {
- ViewGroup parent = (ViewGroup)v.getParent();
- parent.removeView(v);
- notification.view = null;
- }
- }
- */
-
- private void setAreThereNotifications() {
- /*
- boolean ongoing = mOngoingItems.getChildCount() != 0;
- boolean latest = mLatestItems.getChildCount() != 0;
-
- if (mNotificationData.hasClearableItems()) {
- mClearButton.setVisibility(View.VISIBLE);
- } else {
- mClearButton.setVisibility(View.INVISIBLE);
- }
-
- mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE);
- mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE);
-
- if (ongoing || latest) {
- mNoNotificationsTitle.setVisibility(View.GONE);
- } else {
- mNoNotificationsTitle.setVisibility(View.VISIBLE);
- }
- */
- }
-
private void makeExpandedVisible() {
if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
if (mExpandedVisible) {
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index a6124bf..40026fa 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -623,9 +623,7 @@
private PendingIntent makeIntent() {
Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setComponent(new android.content.ComponentName(
- "com.android.contacts",
- "com.android.contacts.ContactsActivity"));
+ intent.addCategory(Intent.CATEGORY_HOME);
return PendingIntent.getActivity(this, 0, intent, 0);
}