Observable: Call out to hasChanged() to figure out if something changes.
bug: 28797950
Change-Id: I3362243c63f72e05ebd72f9243a2d45aa7734c6a
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java
index b13a876..fcd9e2f 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ObservableTest.java
@@ -20,6 +20,7 @@
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
+import java.util.concurrent.atomic.AtomicReference;
public class ObservableTest extends junit.framework.TestCase {
@@ -229,6 +230,24 @@
.elementAt(0).equals(obj));
}
+ static final class AlwaysChangedObservable extends Observable {
+ @Override
+ public boolean hasChanged() {
+ return true;
+ }
+ }
+
+ // http://b/28797950
+ public void test_observableWithOverridenHasChanged() throws Exception {
+ final AtomicReference<Observable> updated = new AtomicReference<>();
+ final Observer observer = (observable1, data) -> updated.set(observable1);
+
+ Observable alwaysChanging = new AlwaysChangedObservable();
+ alwaysChanging.addObserver(observer);
+ alwaysChanging.notifyObservers(null);
+ assertSame(alwaysChanging, updated.get());
+ }
+
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
diff --git a/ojluni/src/main/java/java/util/Observable.java b/ojluni/src/main/java/java/util/Observable.java
index 48c6c13..1d8be3b 100755
--- a/ojluni/src/main/java/java/util/Observable.java
+++ b/ojluni/src/main/java/java/util/Observable.java
@@ -138,18 +138,19 @@
synchronized (this) {
/* We don't want the Observer doing callbacks into
- * arbitrary code while holding its own Monitor.
+ * arbitrary Observables while holding its own Monitor.
* The code where we extract each Observable from
- * the Vector and store the state of the Observer
+ * the ArrayList and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
+ *
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
- if (!changed)
+ if (!hasChanged())
return;
arrLocal = observers.toArray(new Observer[observers.size()]);