summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/Notification.java38
-rw-r--r--core/java/android/widget/RemoteViews.java9
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarIcon.java8
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarNotification.java112
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarNotificationList.aidl (renamed from services/java/com/android/server/status/StatusBarNotification.java)29
-rw-r--r--core/java/com/android/internal/statusbar/StatusBarNotificationList.java164
-rw-r--r--packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java5
-rw-r--r--packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java1
-rw-r--r--packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java2
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java34
-rw-r--r--services/java/com/android/server/status/NotificationData.java44
-rw-r--r--services/java/com/android/server/status/NotificationViewList.java276
-rw-r--r--services/java/com/android/server/status/StatusBarManagerService.java99
13 files changed, 375 insertions, 446 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4d72f73..739aca3 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -341,6 +341,44 @@ public class Notification implements Parcelable
iconLevel = parcel.readInt();
}
+ public Notification clone() {
+ Notification that = new Notification();
+
+ that.when = this.when;
+ that.icon = this.icon;
+ that.number = this.number;
+
+ // PendingIntents are global, so there's no reason (or way) to clone them.
+ that.contentIntent = this.contentIntent;
+ that.deleteIntent = this.deleteIntent;
+
+ if (this.tickerText != null) {
+ that.tickerText = this.tickerText.toString();
+ }
+ if (this.contentView != null) {
+ that.contentView = this.contentView.clone();
+ }
+ that.iconLevel = that.iconLevel;
+ that.sound = this.sound; // android.net.Uri is immutable
+ that.audioStreamType = this.audioStreamType;
+
+ final long[] vibrate = this.vibrate;
+ if (vibrate != null) {
+ final int N = vibrate.length;
+ final long[] vib = that.vibrate = new long[N];
+ System.arraycopy(vibrate, 0, vib, 0, N);
+ }
+
+ that.ledARGB = this.ledARGB;
+ that.ledOnMS = this.ledOnMS;
+ that.ledOffMS = this.ledOffMS;
+ that.defaults = this.defaults;
+
+ that.flags = this.flags;
+
+ return that;
+ }
+
public int describeContents() {
return 0;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 3003580..7a70c80 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -100,6 +100,7 @@ public class RemoteViews implements Parcelable, Filter {
* Base class for all actions that can be performed on an
* inflated view.
*
+ * SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS!!!!!
*/
private abstract static class Action implements Parcelable {
public abstract void apply(View root) throws ActionException;
@@ -568,6 +569,14 @@ public class RemoteViews implements Parcelable, Filter {
}
}
+ public RemoteViews clone() {
+ final RemoteViews that = new RemoteViews(mPackage, mLayoutId);
+ if (mActions != null) {
+ that.mActions = (ArrayList<Action>)mActions.clone();
+ }
+ return that;
+ }
+
public String getPackage() {
return mPackage;
}
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
index 455e17b..e28325c 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -27,6 +27,7 @@ public class StatusBarIcon implements Parcelable {
public int iconId;
public int iconLevel;
public boolean visible = true;
+ public int number;
private StatusBarIcon() {
}
@@ -39,12 +40,14 @@ public class StatusBarIcon implements Parcelable {
public String toString() {
return "StatusBarIcon(pkg=" + this.iconPackage + " id=0x" + Integer.toHexString(this.iconId)
- + " level=" + this.iconLevel + " visible=" + visible + ")";
+ + " level=" + this.iconLevel + " visible=" + visible
+ + " num=" + this.number + " )";
}
public StatusBarIcon clone() {
StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel);
that.visible = this.visible;
+ that.number = this.number;
return that;
}
@@ -60,13 +63,14 @@ public class StatusBarIcon implements Parcelable {
this.iconId = in.readInt();
this.iconLevel = in.readInt();
this.visible = in.readInt() != 0;
+ this.number = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(this.iconPackage);
out.writeInt(this.iconId);
out.writeInt(this.iconLevel);
- out.writeInt(this.visible ? 1 : 0);
+ out.writeInt(this.number);
}
public int describeContents() {
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotification.java
new file mode 100644
index 0000000..ba1525e
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarNotification.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+import android.app.Notification;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.widget.RemoteViews;
+
+
+/*
+boolean clearable = !n.ongoingEvent && ((notification.flags & Notification.FLAG_NO_CLEAR) == 0);
+
+
+// TODO: make this restriction do something smarter like never fill
+// more than two screens. "Why would anyone need more than 80 characters." :-/
+final int maxTickerLen = 80;
+if (truncatedTicker != null && truncatedTicker.length() > maxTickerLen) {
+ truncatedTicker = truncatedTicker.subSequence(0, maxTickerLen);
+}
+*/
+
+public class StatusBarNotification implements Parcelable {
+ public String pkg;
+ public int id;
+ public String tag;
+ Notification notification;
+
+ public StatusBarNotification() {
+ }
+
+ public StatusBarNotification(String pkg, int id, String tag, Notification notification) {
+ if (pkg == null) throw new NullPointerException();
+ if (notification == null) throw new NullPointerException();
+
+ this.pkg = pkg;
+ this.id = id;
+ this.tag = tag;
+ this.notification = notification;
+ }
+
+ public StatusBarNotification(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public void readFromParcel(Parcel in) {
+ this.pkg = in.readString();
+ this.id = in.readInt();
+ if (in.readInt() != 0) {
+ this.tag = in.readString();
+ } else {
+ this.tag = null;
+ }
+ this.notification = new Notification(in);
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(this.pkg);
+ out.writeInt(this.id);
+ if (this.tag != null) {
+ out.writeInt(1);
+ out.writeString(this.tag);
+ } else {
+ out.writeInt(0);
+ }
+ this.notification.writeToParcel(out, flags);
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public static final Parcelable.Creator<StatusBarNotification> CREATOR
+ = new Parcelable.Creator<StatusBarNotification>()
+ {
+ public StatusBarNotification createFromParcel(Parcel parcel)
+ {
+ return new StatusBarNotification(parcel);
+ }
+
+ public StatusBarNotification[] newArray(int size)
+ {
+ return new StatusBarNotification[size];
+ }
+ };
+
+ public StatusBarNotification clone() {
+ return new StatusBarNotification(this.pkg, this.id, this.tag, this.notification.clone());
+ }
+
+ public String toString() {
+ return "StatusBarNotification(package=" + pkg + " tag=" + tag
+ + " notification=" + notification + ")";
+ }
+
+}
+
+
diff --git a/services/java/com/android/server/status/StatusBarNotification.java b/core/java/com/android/internal/statusbar/StatusBarNotificationList.aidl
index 4bb8fdb..10abeee 100644
--- a/services/java/com/android/server/status/StatusBarNotification.java
+++ b/core/java/com/android/internal/statusbar/StatusBarNotificationList.aidl
@@ -1,27 +1,20 @@
/*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (c) 2010, The Android Open Source Project
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.server.status;
+package com.android.internal.statusbar;
-import android.os.IBinder;
-import android.view.View;
+parcelable StatusBarNotificationList;
-public class StatusBarNotification {
- IBinder key;
- NotificationData data;
- View view;
- View contentView;
-}
diff --git a/core/java/com/android/internal/statusbar/StatusBarNotificationList.java b/core/java/com/android/internal/statusbar/StatusBarNotificationList.java
new file mode 100644
index 0000000..2b70f5f
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/StatusBarNotificationList.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.statusbar;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+public class StatusBarNotificationList implements Parcelable {
+ private class Entry {
+ IBinder key;
+ public StatusBarNotification notification;
+
+ void writeToParcel(Parcel out, int flags) {
+ out.writeStrongBinder(key);
+ notification.writeToParcel(out, flags);
+ }
+
+ void readFromParcel(Parcel in) {
+ key = in.readStrongBinder();
+ notification = new StatusBarNotification(in);
+ }
+
+ public Entry clone() {
+ Entry that = new Entry();
+ that.key = this.key;
+ that.notification = this.notification.clone();
+ return that;
+ }
+ }
+
+ private ArrayList<Entry> mEntries = new ArrayList<Entry>();
+
+ public StatusBarNotificationList() {
+ }
+
+ public StatusBarNotificationList(Parcel in) {
+ readFromParcel(in);
+ }
+
+ public void readFromParcel(Parcel in) {
+ final int N = in.readInt();
+ for (int i=0; i<N; i++) {
+ Entry e = new Entry();
+ e.readFromParcel(in);
+ mEntries.add(e);
+ }
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ final int N = mEntries.size();
+ out.writeInt(N);
+ for (int i=0; i<N; i++) {
+ mEntries.get(i).writeToParcel(out, flags);
+ }
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Parcelable.Creator that instantiates StatusBarNotificationList objects
+ */
+ public static final Parcelable.Creator<StatusBarNotificationList> CREATOR
+ = new Parcelable.Creator<StatusBarNotificationList>()
+ {
+ public StatusBarNotificationList createFromParcel(Parcel parcel)
+ {
+ return new StatusBarNotificationList(parcel);
+ }
+
+ public StatusBarNotificationList[] newArray(int size)
+ {
+ return new StatusBarNotificationList[size];
+ }
+ };
+
+ public void copyFrom(StatusBarNotificationList that) {
+ mEntries.clear();
+ final int N = that.mEntries.size();
+ for (int i=0; i<N; i++) {
+ mEntries.add(that.mEntries.get(i).clone());
+ }
+ }
+
+ public void dump(PrintWriter pw) {
+ final int N = mEntries.size();
+ pw.println("Notification list:");
+ for (int i=0; i<N; i++) {
+ Entry e = mEntries.get(i);
+ pw.printf(" %2d: %s\n", i, e.notification.toString());
+ }
+ }
+
+
+ public int size() {
+ return mEntries.size();
+ }
+
+ public IBinder add(StatusBarNotification notification) {
+ if (notification == null) throw new NullPointerException();
+
+ Entry entry = new Entry();
+ entry.key = new Binder();
+ entry.notification = notification.clone();
+
+ // TODO: Sort correctly by "when"
+ mEntries.add(entry);
+
+ return entry.key;
+ }
+
+ public void update(IBinder key, StatusBarNotification notification) {
+ final int index = getIndex(key);
+ if (index < 0) {
+ throw new IllegalArgumentException("got invalid key: " + key);
+ }
+ final Entry entry = mEntries.get(index);
+ entry.notification = notification.clone();
+ }
+
+ public void remove(IBinder key) {
+ final int index = getIndex(key);
+ if (index < 0) {
+ throw new IllegalArgumentException("got invalid key: " + key);
+ }
+ mEntries.remove(index);
+ }
+
+ public int getIndex(IBinder key) {
+ final ArrayList<Entry> entries = mEntries;
+ final int N = entries.size();
+ for (int i=0; i<N; i++) {
+ if (entries.get(i).key == key) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public StatusBarNotification getNotification(int index) {
+ return mEntries.get(index).notification;
+ }
+}
+
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 bc02625..1ae3585 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/PhoneStatusBarService.java
@@ -426,6 +426,11 @@ public class PhoneStatusBarService extends StatusBarService {
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="
diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java
index 874fcfa..58b9822 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarIconView.java
@@ -61,6 +61,7 @@ public class StatusBarIconView extends AnimatedImageView {
&& mIcon.visible == icon.visible;
if (!iconEquals) {
setImageDrawable(getIcon(icon));
+ // TODO: What if getIcon returns null?
}
if (!levelEquals) {
setImageLevel(icon.iconLevel);
diff --git a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java
index d783c11..20f3552 100644
--- a/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java
+++ b/packages/StatusBarPhone/src/com/android/policy/statusbar/phone/StatusBarService.java
@@ -37,8 +37,6 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
-import com.android.server.status.NotificationData;
-
public abstract class StatusBarService extends Service implements CommandQueue.Callbacks {
private static final String TAG = "StatusBarService";
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 327e18b..d3fbd6d 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -17,7 +17,7 @@
package com.android.server;
import com.android.server.status.IconData;
-import com.android.server.status.NotificationData;
+import com.android.internal.statusbar.StatusBarNotification;
import com.android.server.status.StatusBarManagerService;
import android.app.ActivityManagerNative;
@@ -705,36 +705,12 @@ class NotificationManagerService extends INotificationManager.Stub
}
if (notification.icon != 0) {
- IconData icon = IconData.makeIcon(null, pkg, notification.icon,
- notification.iconLevel,
- notification.number);
- CharSequence truncatedTicker = notification.tickerText;
-
- // TODO: make this restriction do something smarter like never fill
- // more than two screens. "Why would anyone need more than 80 characters." :-/
- final int maxTickerLen = 80;
- if (truncatedTicker != null && truncatedTicker.length() > maxTickerLen) {
- truncatedTicker = truncatedTicker.subSequence(0, maxTickerLen);
- }
-
- NotificationData n = new NotificationData();
- n.pkg = pkg;
- n.tag = tag;
- n.id = id;
- n.when = notification.when;
- n.tickerText = truncatedTicker;
- n.ongoingEvent = (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0;
- if (!n.ongoingEvent && (notification.flags & Notification.FLAG_NO_CLEAR) == 0) {
- n.clearable = true;
- }
- n.contentView = notification.contentView;
- n.contentIntent = notification.contentIntent;
- n.deleteIntent = notification.deleteIntent;
+ StatusBarNotification n = new StatusBarNotification(pkg, id, tag, notification);
if (old != null && old.statusBarKey != null) {
r.statusBarKey = old.statusBarKey;
long identity = Binder.clearCallingIdentity();
try {
- mStatusBar.updateNotification(r.statusBarKey, icon, n);
+ mStatusBar.updateNotification(r.statusBarKey, n);
}
finally {
Binder.restoreCallingIdentity(identity);
@@ -742,16 +718,14 @@ class NotificationManagerService extends INotificationManager.Stub
} else {
long identity = Binder.clearCallingIdentity();
try {
- r.statusBarKey = mStatusBar.addNotification(icon, n);
+ r.statusBarKey = mStatusBar.addNotification(n);
mAttentionLight.pulse();
}
finally {
Binder.restoreCallingIdentity(identity);
}
}
-
sendAccessibilityEvent(notification, pkg);
-
} else {
if (old != null && old.statusBarKey != null) {
long identity = Binder.clearCallingIdentity();
diff --git a/services/java/com/android/server/status/NotificationData.java b/services/java/com/android/server/status/NotificationData.java
deleted file mode 100644
index 71f01ca..0000000
--- a/services/java/com/android/server/status/NotificationData.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.status;
-
-import android.app.PendingIntent;
-import android.widget.RemoteViews;
-
-public class NotificationData {
- public String pkg;
- public String tag;
- public int id;
- public CharSequence tickerText;
-
- public long when;
- public boolean ongoingEvent;
- public boolean clearable;
-
- public RemoteViews contentView;
- public PendingIntent contentIntent;
-
- public PendingIntent deleteIntent;
-
- public String toString() {
- return "NotificationData(package=" + pkg + " id=" + id + " tickerText=" + tickerText
- + " ongoingEvent=" + ongoingEvent + " contentIntent=" + contentIntent
- + " deleteIntent=" + deleteIntent
- + " clearable=" + clearable
- + " contentView=" + contentView + " when=" + when + ")";
- }
-}
diff --git a/services/java/com/android/server/status/NotificationViewList.java b/services/java/com/android/server/status/NotificationViewList.java
deleted file mode 100644
index e18e9dd..0000000
--- a/services/java/com/android/server/status/NotificationViewList.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.status;
-
-import android.os.IBinder;
-import android.util.Slog;
-import android.view.View;
-import java.util.ArrayList;
-
-public class NotificationViewList {
- private ArrayList<StatusBarNotification> mOngoing = new ArrayList();
- private ArrayList<StatusBarNotification> mLatest = new ArrayList();
-
- public NotificationViewList() {
- }
-
- private static final int indexInList(ArrayList<StatusBarNotification> list, NotificationData n){
- final int N = list.size();
- for (int i=0; i<N; i++) {
- StatusBarNotification that = list.get(i);
- if (that.data == n) {
- return i;
- }
- }
- return -1;
- }
-
- int getIconIndex(NotificationData n) {
- final int ongoingSize = mOngoing.size();
- final int latestSize = mLatest.size();
- if (n.ongoingEvent) {
- int index = indexInList(mOngoing, n);
- if (index >= 0) {
- return latestSize + index + 1;
- } else {
- return -1;
- }
- } else {
- return indexInList(mLatest, n) + 1;
- }
- }
-
- void remove(StatusBarNotification notification) {
- NotificationData n = notification.data;
- int index;
- index = indexInList(mOngoing, n);
- if (index >= 0) {
- mOngoing.remove(index);
- return;
- }
- index = indexInList(mLatest, n);
- if (index >= 0) {
- mLatest.remove(index);
- return;
- }
- }
-
- ArrayList<StatusBarNotification> notificationsForPackage(String packageName) {
- ArrayList<StatusBarNotification> list = new ArrayList<StatusBarNotification>();
- int N = mOngoing.size();
- for (int i=0; i<N; i++) {
- if (matchPackage(mOngoing.get(i), packageName)) {
- list.add(mOngoing.get(i));
- }
- }
- N = mLatest.size();
- for (int i=0; i<N; i++) {
- if (matchPackage(mLatest.get(i), packageName)) {
- list.add(mLatest.get(i));
- }
- }
- return list;
- }
-
- private final boolean matchPackage(StatusBarNotification snb, String packageName) {
- if (snb.data.contentIntent != null) {
- if (snb.data.contentIntent.getTargetPackage().equals(packageName)) {
- return true;
- }
- } else if (snb.data.pkg != null && snb.data.pkg.equals(packageName)) {
- return true;
- }
- return false;
- }
-
- private static final int indexForKey(ArrayList<StatusBarNotification> list, IBinder key) {
- final int N = list.size();
- for (int i=0; i<N; i++) {
- if (list.get(i).key == key) {
- return i;
- }
- }
- return -1;
- }
-
- StatusBarNotification get(IBinder key) {
- int index;
- index = indexForKey(mOngoing, key);
- if (index >= 0) {
- return mOngoing.get(index);
- }
- index = indexForKey(mLatest, key);
- if (index >= 0) {
- return mLatest.get(index);
- }
- return null;
- }
-
- // gets the index of the notification's view in its expanded parent view
- int getExpandedIndex(StatusBarNotification notification) {
- ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
- final IBinder key = notification.key;
- int index = 0;
- // (the view order is backwards from this list order)
- for (int i=list.size()-1; i>=0; i--) {
- StatusBarNotification item = list.get(i);
- if (item.key == key) {
- return index;
- }
- if (item.view != null) {
- index++;
- }
- }
- Slog.e(StatusBarManagerService.TAG, "Couldn't find notification in NotificationViewList.");
- Slog.e(StatusBarManagerService.TAG, "notification=" + notification);
- dump(notification);
- return 0;
- }
-
- void clearViews() {
- int N = mOngoing.size();
- for (int i=0; i<N; i++) {
- mOngoing.get(i).view = null;
- }
- N = mLatest.size();
- for (int i=0; i<N; i++) {
- mLatest.get(i).view = null;
- }
- }
-
- int ongoingCount() {
- return mOngoing.size();
- }
-
- int latestCount() {
- return mLatest.size();
- }
-
- StatusBarNotification getOngoing(int index) {
- return mOngoing.get(index);
- }
-
- StatusBarNotification getLatest(int index) {
- return mLatest.get(index);
- }
-
- int size() {
- return mOngoing.size() + mLatest.size();
- }
-
- void add(StatusBarNotification notification) {
- if (StatusBarManagerService.SPEW) {
- Slog.d(StatusBarManagerService.TAG, "before add NotificationViewList"
- + " notification.data.ongoingEvent=" + notification.data.ongoingEvent);
- dump(notification);
- }
-
- ArrayList<StatusBarNotification> list = notification.data.ongoingEvent ? mOngoing : mLatest;
- long when = notification.data.when;
- final int N = list.size();
- int index = N;
- for (int i=0; i<N; i++) {
- StatusBarNotification that = list.get(i);
- if (that.data.when > when) {
- index = i;
- break;
- }
- }
- list.add(index, notification);
-
- if (StatusBarManagerService.SPEW) {
- Slog.d(StatusBarManagerService.TAG, "after add NotificationViewList index=" + index);
- dump(notification);
- }
- }
-
- void dump(StatusBarNotification notification) {
- if (StatusBarManagerService.SPEW) {
- boolean showTime = false;
- String s = "";
- for (int i=0; i<mOngoing.size(); i++) {
- StatusBarNotification that = mOngoing.get(i);
- if (that.key == notification.key) {
- s += "[";
- }
- if (showTime) {
- s += that.data.when;
- } else {
- s += that.data.pkg + "/" + that.data.id + "/" + that.view;
- }
- if (that.key == notification.key) {
- s += "]";
- }
- s += " ";
- }
- Slog.d(StatusBarManagerService.TAG, "NotificationViewList ongoing: " + s);
-
- s = "";
- for (int i=0; i<mLatest.size(); i++) {
- StatusBarNotification that = mLatest.get(i);
- if (that.key == notification.key) {
- s += "[";
- }
- if (showTime) {
- s += that.data.when;
- } else {
- s += that.data.pkg + "/" + that.data.id + "/" + that.view;
- }
- if (that.key == notification.key) {
- s += "]";
- }
- s += " ";
- }
- Slog.d(StatusBarManagerService.TAG, "NotificationViewList latest: " + s);
- }
- }
-
- StatusBarNotification get(View view) {
- int N = mOngoing.size();
- for (int i=0; i<N; i++) {
- StatusBarNotification notification = mOngoing.get(i);
- View v = notification.view;
- if (v == view) {
- return notification;
- }
- }
- N = mLatest.size();
- for (int i=0; i<N; i++) {
- StatusBarNotification notification = mLatest.get(i);
- View v = notification.view;
- if (v == view) {
- return notification;
- }
- }
- return null;
- }
-
- void update(StatusBarNotification notification) {
- remove(notification);
- add(notification);
- }
-
- boolean hasClearableItems() {
- int N = mLatest.size();
- for (int i=0; i<N; i++) {
- if (mLatest.get(i).data.clearable) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/services/java/com/android/server/status/StatusBarManagerService.java b/services/java/com/android/server/status/StatusBarManagerService.java
index a59b914..f4678c3 100644
--- a/services/java/com/android/server/status/StatusBarManagerService.java
+++ b/services/java/com/android/server/status/StatusBarManagerService.java
@@ -36,6 +36,8 @@ import com.android.internal.statusbar.IStatusBar;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.statusbar.StatusBarIconList;
+import com.android.internal.statusbar.StatusBarNotification;
+import com.android.internal.statusbar.StatusBarNotificationList;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -60,10 +62,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub
NotificationCallbacks mNotificationCallbacks;
volatile IStatusBar mBar;
StatusBarIconList mIcons = new StatusBarIconList();
- private UninstallReceiver mUninstallReceiver;
-
- // expanded notifications
- NotificationViewList mNotificationData = new NotificationViewList();
+ StatusBarNotificationList mNotifications = new StatusBarNotificationList();
// for disabling the status bar
ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
@@ -93,7 +92,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
*/
public StatusBarManagerService(Context context) {
mContext = context;
- mUninstallReceiver = new UninstallReceiver();
final Resources res = context.getResources();
mIcons.defineSlots(res.getStringArray(com.android.internal.R.array.status_bar_icon_order));
@@ -266,15 +264,29 @@ public class StatusBarManagerService extends IStatusBarService.Stub
Slog.d(TAG, "visibilityChanged visible=" + visible);
}
- public IBinder addNotification(IconData iconData, NotificationData notificationData) {
- return new Binder();
+ // ================================================================================
+ // Callbacks for NotificationManagerService.
+ // ================================================================================
+ public IBinder addNotification(StatusBarNotification notification) {
+ synchronized (mNotifications) {
+ IBinder key = mNotifications.add(notification);
+ // TODO: tell mBar
+ return key;
+ }
}
- public void updateNotification(IBinder key, IconData iconData,
- NotificationData notificationData) {
+ public void updateNotification(IBinder key, StatusBarNotification notification) {
+ synchronized (mNotifications) {
+ mNotifications.update(key, notification);
+ // TODO: tell mBar
+ }
}
public void removeNotification(IBinder key) {
+ synchronized (mNotifications) {
+ mNotifications.remove(key);
+ // TODO: tell mBar
+ }
}
// ================================================================================
@@ -336,12 +348,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// Always called from UI thread
// ================================================================================
- StatusBarNotification getNotification(IBinder key) {
- synchronized (mNotificationData) {
- return mNotificationData.get(key);
- }
- }
-
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
@@ -354,23 +360,11 @@ public class StatusBarManagerService extends IStatusBarService.Stub
synchronized (mIcons) {
mIcons.dump(pw);
}
-
- synchronized (mNotificationData) {
- int N = mNotificationData.ongoingCount();
- pw.println(" ongoingCount.size=" + N);
- for (int i=0; i<N; i++) {
- StatusBarNotification n = mNotificationData.getOngoing(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
- }
- N = mNotificationData.latestCount();
- pw.println(" ongoingCount.size=" + N);
- for (int i=0; i<N; i++) {
- StatusBarNotification n = mNotificationData.getLatest(i);
- pw.println(" [" + i + "] key=" + n.key + " view=" + n.view);
- pw.println(" data=" + n.data);
- }
+
+ synchronized (mNotifications) {
+ mNotifications.dump(pw);
}
+
synchronized (mDisableRecords) {
final int N = mDisableRecords.size();
pw.println(" mDisableRecords.size=" + N
@@ -422,47 +416,4 @@ public class StatusBarManagerService extends IStatusBarService.Stub
}
};
-
- class UninstallReceiver extends BroadcastReceiver {
- public UninstallReceiver() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- filter.addDataScheme("package");
- mContext.registerReceiver(this, filter);
- IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiver(this, sdFilter);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- String pkgList[] = null;
- if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
- pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
- } else {
- Uri data = intent.getData();
- if (data != null) {
- String pkg = data.getSchemeSpecificPart();
- if (pkg != null) {
- pkgList = new String[]{pkg};
- }
- }
- }
- ArrayList<StatusBarNotification> list = null;
- if (pkgList != null) {
- synchronized (StatusBarManagerService.this) {
- for (String pkg : pkgList) {
- list = mNotificationData.notificationsForPackage(pkg);
- }
- }
- }
-
- if (list != null) {
- final int N = list.size();
- for (int i=0; i<N; i++) {
- // TODO: removeIcon(list.get(i).key);
- }
- }
- }
- }
}