summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/ContentService.java53
-rw-r--r--core/tests/coretests/src/android/content/ObserverNodeTest.java35
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();
}