am 89837b25: Merge "Fix StatusBarService deadlock for real this time." into froyo

Merge commit '89837b25c85929b29288fd42727c44093548fced' into kraken

* commit '89837b25c85929b29288fd42727c44093548fced':
  Fix StatusBarService deadlock for real this time.
This commit is contained in:
Joe Onorato
2010-03-26 14:31:23 -07:00
committed by Android Git Automerger

View File

@@ -153,6 +153,7 @@ public class StatusBarService extends IStatusBar.Stub
StatusBarView mStatusBarView; StatusBarView mStatusBarView;
int mPixelFormat; int mPixelFormat;
H mHandler = new H(); H mHandler = new H();
Object mQueueLock = new Object();
ArrayList<PendingOp> mQueue = new ArrayList<PendingOp>(); ArrayList<PendingOp> mQueue = new ArrayList<PendingOp>();
NotificationCallbacks mNotificationCallbacks; NotificationCallbacks mNotificationCallbacks;
@@ -440,7 +441,7 @@ public class StatusBarService extends IStatusBar.Stub
} }
private void addPendingOp(int code, IBinder key, IconData data, NotificationData n, int i) { private void addPendingOp(int code, IBinder key, IconData data, NotificationData n, int i) {
synchronized (mQueue) { synchronized (mQueueLock) {
PendingOp op = new PendingOp(); PendingOp op = new PendingOp();
op.key = key; op.key = key;
op.code = code; op.code = code;
@@ -455,7 +456,7 @@ public class StatusBarService extends IStatusBar.Stub
} }
private void addPendingOp(int code, IBinder key, boolean visible) { private void addPendingOp(int code, IBinder key, boolean visible) {
synchronized (mQueue) { synchronized (mQueueLock) {
PendingOp op = new PendingOp(); PendingOp op = new PendingOp();
op.key = key; op.key = key;
op.code = code; op.code = code;
@@ -468,7 +469,7 @@ public class StatusBarService extends IStatusBar.Stub
} }
private void addPendingOp(int code, int integer) { private void addPendingOp(int code, int integer) {
synchronized (mQueue) { synchronized (mQueueLock) {
PendingOp op = new PendingOp(); PendingOp op = new PendingOp();
op.code = code; op.code = code;
op.integer = integer; op.integer = integer;
@@ -557,20 +558,24 @@ public class StatusBarService extends IStatusBar.Stub
doRevealAnimation(); doRevealAnimation();
return; return;
} }
boolean expand = false;
boolean doExpand = false;
boolean doDisable = false;
int disableWhat = 0;
synchronized (mQueue) { ArrayList<PendingOp> queue;
synchronized (mQueueLock) {
queue = mQueue;
mQueue = new ArrayList<PendingOp>();
}
boolean wasExpanded = mExpanded; boolean wasExpanded = mExpanded;
// for each one in the queue, find all of the ones with the same key // for each one in the queue, find all of the ones with the same key
// and collapse that down into a final op and/or call to setVisibility, etc // and collapse that down into a final op and/or call to setVisibility, etc
expand = wasExpanded; boolean expand = wasExpanded;
int N = mQueue.size(); boolean doExpand = false;
boolean doDisable = false;
int disableWhat = 0;
int N = queue.size();
while (N > 0) { while (N > 0) {
PendingOp op = mQueue.get(0); PendingOp op = queue.get(0);
boolean doOp = false; boolean doOp = false;
boolean visible = false; boolean visible = false;
boolean doVisibility = false; boolean doVisibility = false;
@@ -593,7 +598,7 @@ public class StatusBarService extends IStatusBar.Stub
if (alwaysHandle(op.code)) { if (alwaysHandle(op.code)) {
// coalesce these // coalesce these
for (int i=1; i<N; i++) { for (int i=1; i<N; i++) {
PendingOp o = mQueue.get(i); PendingOp o = queue.get(i);
if (!alwaysHandle(o.code) && o.key == op.key) { if (!alwaysHandle(o.code) && o.key == op.key) {
if (o.code == OP_SET_VISIBLE) { if (o.code == OP_SET_VISIBLE) {
visible = o.visible; visible = o.visible;
@@ -608,14 +613,14 @@ public class StatusBarService extends IStatusBar.Stub
op.iconData = o.iconData; op.iconData = o.iconData;
op.notificationData = o.notificationData; op.notificationData = o.notificationData;
} }
mQueue.remove(i); queue.remove(i);
i--; i--;
N--; N--;
} }
} }
} }
mQueue.remove(0); queue.remove(0);
N--; N--;
if (doOp) { if (doOp) {
@@ -638,13 +643,9 @@ public class StatusBarService extends IStatusBar.Stub
} }
} }
if (mQueue.size() != 0) { if (queue.size() != 0) {
throw new RuntimeException("Assertion failed: mQueue.size=" + mQueue.size()); throw new RuntimeException("Assertion failed: queue.size=" + queue.size());
} }
}
// This must be done outside the synchronized block above to prevent a deadlock where
// we call into the NotificationManagerService and it is in turn attempting to post a
// message to our queue.
if (doExpand) { if (doExpand) {
// this is last so that we capture all of the pending changes before doing it // this is last so that we capture all of the pending changes before doing it
if (expand) { if (expand) {
@@ -1397,7 +1398,7 @@ public class StatusBarService extends IStatusBar.Stub
return; return;
} }
synchronized (mQueue) { synchronized (mQueueLock) {
pw.println("Current Status Bar state:"); pw.println("Current Status Bar state:");
pw.println(" mExpanded=" + mExpanded pw.println(" mExpanded=" + mExpanded
+ ", mExpandedVisible=" + mExpandedVisible); + ", mExpandedVisible=" + mExpandedVisible);