Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89837b25 authored by Joe Onorato's avatar Joe Onorato Committed by Android (Google) Code Review
Browse files

Merge "Fix StatusBarService deadlock for real this time." into froyo

parents 4ea1eea5 1aedcce9
Loading
Loading
Loading
Loading
+81 −80
Original line number Original line Diff line number Diff line
@@ -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);