diff options
| author | Fred Quintana <fredq@google.com> | 2010-03-02 11:18:16 -0800 |
|---|---|---|
| committer | Fred Quintana <fredq@google.com> | 2010-03-02 11:18:16 -0800 |
| commit | 002ffad599964653186c01f8e07fadc82dc0acee (patch) | |
| tree | 5dc5eee5fe6024db511665ab88f9c6a540cddf4f /core/java/android/content/ContentService.java | |
| parent | aceb6fe23edacf0a945ff8f73fbf31ba1fdc2f0e (diff) | |
change ObserverNode.binderDied() to lock the root node before manipulating
the observers tree by calling removeObserverLocked()
http://b/issue?id=2457485
Diffstat (limited to 'core/java/android/content/ContentService.java')
| -rw-r--r-- | core/java/android/content/ContentService.java | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java index b5a78fa95c71..0477d6dfc3e9 100644 --- a/core/java/android/content/ContentService.java +++ b/core/java/android/content/ContentService.java @@ -32,7 +32,6 @@ import android.Manifest; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Collection; import java.util.List; /** @@ -104,7 +103,7 @@ public final class ContentService extends IContentService.Stub { throw new IllegalArgumentException("You must pass a valid uri and observer"); } synchronized (mRootNode) { - mRootNode.addObserver(uri, observer, notifyForDescendents); + mRootNode.addObserverLocked(uri, observer, notifyForDescendents, mRootNode); if (Config.LOGV) Log.v(TAG, "Registered observer " + observer + " at " + uri + " with notifyForDescendents " + notifyForDescendents); } @@ -115,7 +114,7 @@ public final class ContentService extends IContentService.Stub { throw new IllegalArgumentException("You must pass a valid observer"); } synchronized (mRootNode) { - mRootNode.removeObserver(observer); + mRootNode.removeObserverLocked(observer); if (Config.LOGV) Log.v(TAG, "Unregistered observer " + observer); } } @@ -132,7 +131,7 @@ public final class ContentService extends IContentService.Stub { try { ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); synchronized (mRootNode) { - mRootNode.collectObservers(uri, 0, observer, observerWantsSelfNotifications, + mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications, calls); } final int numCalls = calls.size(); @@ -470,10 +469,12 @@ public final class ContentService extends IContentService.Stub { */ public static final class ObserverNode { private class ObserverEntry implements IBinder.DeathRecipient { - public IContentObserver observer; - public boolean notifyForDescendents; + public final IContentObserver observer; + public final boolean notifyForDescendents; + private final Object observersLock; - public ObserverEntry(IContentObserver o, boolean n) { + public ObserverEntry(IContentObserver o, boolean n, Object observersLock) { + this.observersLock = observersLock; observer = o; notifyForDescendents = n; try { @@ -484,7 +485,9 @@ public final class ContentService extends IContentService.Stub { } public void binderDied() { - removeObserver(observer); + synchronized (observersLock) { + removeObserverLocked(observer); + } } } @@ -519,16 +522,16 @@ public final class ContentService extends IContentService.Stub { return uri.getPathSegments().size() + 1; } - public void addObserver(Uri uri, IContentObserver observer, boolean notifyForDescendents) { - addObserver(uri, 0, observer, notifyForDescendents); + public void addObserverLocked(Uri uri, IContentObserver observer, + boolean notifyForDescendents, Object observersLock) { + addObserverLocked(uri, 0, observer, notifyForDescendents, observersLock); } - private void addObserver(Uri uri, int index, IContentObserver observer, - boolean notifyForDescendents) { - + private void addObserverLocked(Uri uri, int index, IContentObserver observer, + boolean notifyForDescendents, Object observersLock) { // If this is the leaf node add the observer if (index == countUriSegments(uri)) { - mObservers.add(new ObserverEntry(observer, notifyForDescendents)); + mObservers.add(new ObserverEntry(observer, notifyForDescendents, observersLock)); return; } @@ -538,7 +541,7 @@ public final class ContentService extends IContentService.Stub { for (int i = 0; i < N; i++) { ObserverNode node = mChildren.get(i); if (node.mName.equals(segment)) { - node.addObserver(uri, index + 1, observer, notifyForDescendents); + node.addObserverLocked(uri, index + 1, observer, notifyForDescendents, observersLock); return; } } @@ -546,13 +549,13 @@ public final class ContentService extends IContentService.Stub { // No child found, create one ObserverNode node = new ObserverNode(segment); mChildren.add(node); - node.addObserver(uri, index + 1, observer, notifyForDescendents); + node.addObserverLocked(uri, index + 1, observer, notifyForDescendents, observersLock); } - public boolean removeObserver(IContentObserver observer) { + public boolean removeObserverLocked(IContentObserver observer) { int size = mChildren.size(); for (int i = 0; i < size; i++) { - boolean empty = mChildren.get(i).removeObserver(observer); + boolean empty = mChildren.get(i).removeObserverLocked(observer); if (empty) { mChildren.remove(i); i--; @@ -578,10 +581,8 @@ public final class ContentService extends IContentService.Stub { return false; } - private void collectMyObservers(Uri uri, - boolean leaf, IContentObserver observer, boolean selfNotify, - ArrayList<ObserverCall> calls) - { + private void collectMyObserversLocked(boolean leaf, IContentObserver observer, + boolean selfNotify, ArrayList<ObserverCall> calls) { int N = mObservers.size(); IBinder observerBinder = observer == null ? null : observer.asBinder(); for (int i = 0; i < N; i++) { @@ -600,17 +601,17 @@ public final class ContentService extends IContentService.Stub { } } - public void collectObservers(Uri uri, int index, IContentObserver observer, + public void collectObserversLocked(Uri uri, int index, IContentObserver observer, boolean selfNotify, ArrayList<ObserverCall> calls) { String segment = null; int segmentCount = countUriSegments(uri); if (index >= segmentCount) { // This is the leaf node, notify all observers - collectMyObservers(uri, true, observer, selfNotify, calls); + collectMyObserversLocked(true, observer, selfNotify, calls); } else if (index < segmentCount){ segment = getUriSegment(uri, index); // Notify any observers at this level who are interested in descendents - collectMyObservers(uri, false, observer, selfNotify, calls); + collectMyObserversLocked(false, observer, selfNotify, calls); } int N = mChildren.size(); @@ -618,7 +619,7 @@ public final class ContentService extends IContentService.Stub { ObserverNode node = mChildren.get(i); if (segment == null || node.mName.equals(segment)) { // We found the child, - node.collectObservers(uri, index + 1, observer, selfNotify, calls); + node.collectObserversLocked(uri, index + 1, observer, selfNotify, calls); if (segment != null) { break; } |
