diff options
| -rw-r--r-- | core/java/android/content/ContentService.java | 53 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/content/ObserverNodeTest.java | 35 |
2 files changed, 44 insertions, 44 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; } diff --git a/core/tests/coretests/src/android/content/ObserverNodeTest.java b/core/tests/coretests/src/android/content/ObserverNodeTest.java index 68cc75b7b2ad..736c75926db4 100644 --- a/core/tests/coretests/src/android/content/ObserverNodeTest.java +++ b/core/tests/coretests/src/android/content/ObserverNodeTest.java @@ -24,50 +24,49 @@ import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.test.AndroidTestCase; -import android.util.Log; -public class ObserverNodeTest extends AndroidTestCase { +public class ObserverNodeTest extends AndroidTestCase { static class TestObserver extends ContentObserver { public TestObserver() { super(new Handler()); } } - + public void testUri() { ObserverNode root = new ObserverNode(""); Uri[] uris = new Uri[] { Uri.parse("content://c/a/"), Uri.parse("content://c/"), - Uri.parse("content://x/"), + Uri.parse("content://x/"), Uri.parse("content://c/b/"), Uri.parse("content://c/a/a1/1/"), Uri.parse("content://c/a/a1/2/"), Uri.parse("content://c/b/1/"), Uri.parse("content://c/b/2/"), }; - + int[] nums = new int[] {4, 7, 1, 4, 2, 2, 3, 3}; - + // special case - root.addObserver(uris[0], new TestObserver().getContentObserver(), false); + root.addObserverLocked(uris[0], new TestObserver().getContentObserver(), false, root); for(int i = 1; i < uris.length; i++) { - root.addObserver(uris[i], new TestObserver().getContentObserver(), true); + root.addObserverLocked(uris[i], new TestObserver().getContentObserver(), true, root); } - + ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); - + for (int i = nums.length - 1; i >=0; --i) { - root.collectObservers(uris[i], 0, null, false, calls); + root.collectObserversLocked(uris[i], 0, null, false, calls); assertEquals(nums[i], calls.size()); calls.clear(); } } - + public void testUriNotNotify() { ObserverNode root = new ObserverNode(""); Uri[] uris = new Uri[] { Uri.parse("content://c/"), - Uri.parse("content://x/"), + Uri.parse("content://x/"), Uri.parse("content://c/a/"), Uri.parse("content://c/b/"), Uri.parse("content://c/a/1/"), @@ -76,15 +75,15 @@ public class ObserverNodeTest extends AndroidTestCase { Uri.parse("content://c/b/2/"), }; int[] nums = new int[] {7, 1, 3, 3, 1, 1, 1, 1}; - + for(int i = 0; i < uris.length; i++) { - root.addObserver(uris[i], new TestObserver().getContentObserver(), false); + root.addObserverLocked(uris[i], new TestObserver().getContentObserver(), false, root); } - + ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); - + for (int i = uris.length - 1; i >=0; --i) { - root.collectObservers(uris[i], 0, null, false, calls); + root.collectObserversLocked(uris[i], 0, null, false, calls); assertEquals(nums[i], calls.size()); calls.clear(); } |