diff --git a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ContextDataManager.java b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ContextDataManager.java index f14da5a0..a1f97805 100644 --- a/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ContextDataManager.java +++ b/launchdarkly-android-client-sdk/src/main/java/com/launchdarkly/sdk/android/ContextDataManager.java @@ -282,7 +282,9 @@ public boolean upsert(@NonNull Flag flag) { } environmentStore.setContextData(contextId, updatedFlags); - notifyFlagListeners(Collections.singletonList(flag.getKey())); + Collection updatedFlag = Collections.singletonList(flag.getKey()); + notifyAllFlagsListeners(updatedFlag); + notifyFlagListeners(updatedFlag); return true; } diff --git a/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/ContextDataManagerListenersTest.java b/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/ContextDataManagerListenersTest.java index df11732c..33f3373e 100644 --- a/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/ContextDataManagerListenersTest.java +++ b/launchdarkly-android-client-sdk/src/test/java/com/launchdarkly/sdk/android/ContextDataManagerListenersTest.java @@ -8,6 +8,7 @@ import org.junit.Test; +import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -36,12 +37,15 @@ public void listenerIsCalledOnUpdate() throws InterruptedException { Flag flag = new FlagBuilder("flag").version(1).build(); final ContextDataManager manager = createDataManager(); AwaitableFlagListener listener = new AwaitableFlagListener(); + AwaitableFlagListener allFlagsListener = new AwaitableFlagListener(); manager.registerListener(flag.getKey(), listener); + manager.registerAllFlagsListener(allFlagsListener); manager.upsert(flag); assertEquals(flag.getKey(), listener.expectUpdate(5, TimeUnit.SECONDS)); + assertEquals(flag.getKey(), allFlagsListener.expectUpdate(5, TimeUnit.SECONDS)); } @Test @@ -49,12 +53,15 @@ public void listenerIsCalledOnDelete() throws InterruptedException { Flag flag = Flag.deletedItemPlaceholder("flag", 1); final ContextDataManager manager = createDataManager(); AwaitableFlagListener listener = new AwaitableFlagListener(); + AwaitableFlagListener allFlagsListener = new AwaitableFlagListener(); manager.registerListener(flag.getKey(), listener); + manager.registerAllFlagsListener(allFlagsListener); manager.upsert(flag); assertEquals(flag.getKey(), listener.expectUpdate(5, TimeUnit.SECONDS)); + assertEquals(flag.getKey(), allFlagsListener.expectUpdate(5, TimeUnit.SECONDS)); } @Test @@ -62,15 +69,19 @@ public void listenerIsNotCalledAfterUnregistering() throws InterruptedException Flag flag = new FlagBuilder("flag").version(1).build(); final ContextDataManager manager = createDataManager(); AwaitableFlagListener listener = new AwaitableFlagListener(); + AwaitableFlagListener allFlagsListener = new AwaitableFlagListener(); manager.registerListener(flag.getKey(), listener); manager.unregisterListener(flag.getKey(), listener); + manager.registerAllFlagsListener(allFlagsListener); + manager.unregisterAllFlagsListener(allFlagsListener); manager.upsert(flag); // Unfortunately we are testing that an asynchronous method is *not* called, we just have to // wait a bit to be sure. listener.expectNoUpdates(100, TimeUnit.MILLISECONDS); + allFlagsListener.expectNoUpdates(100, TimeUnit.MILLISECONDS); verifyAll(); } @@ -80,16 +91,20 @@ public void listenerIsCalledOnMainThread() throws InterruptedException { Flag flag = Flag.deletedItemPlaceholder("flag", 1); final ContextDataManager manager = createDataManager(); AwaitableFlagListener listener = new AwaitableFlagListener(); + AwaitableFlagListener allFlagsListener = new AwaitableFlagListener(); manager.registerListener(flag.getKey(), listener); + manager.registerAllFlagsListener(allFlagsListener); manager.upsert(flag); listener.expectUpdate(5, TimeUnit.SECONDS); + allFlagsListener.expectUpdate(5, TimeUnit.SECONDS); assertTrue(listener.isCalledFromMainThread()); + assertTrue(allFlagsListener.isCalledFromMainThread()); } - private class AwaitableFlagListener implements FeatureFlagChangeListener { + private class AwaitableFlagListener implements FeatureFlagChangeListener, LDAllFlagsListener { private final BlockingQueue flagKeysUpdated = new LinkedBlockingQueue<>(); private volatile boolean calledFromMainThread; @@ -99,6 +114,12 @@ public void onFeatureFlagChange(String flagKey) { flagKeysUpdated.add(flagKey); } + @Override + public void onChange(List flagKey) { + calledFromMainThread = taskExecutor.isThisTheFakeMainThread(); + flagKeysUpdated.addAll(flagKey); + } + public String expectUpdate(long timeout, TimeUnit timeoutUnit) { try { String flagKey = flagKeysUpdated.poll(timeout, timeoutUnit);