diff options
author | Neil Fuller <nfuller@google.com> | 2014-09-03 17:01:10 +0100 |
---|---|---|
committer | Neil Fuller <nfuller@google.com> | 2014-09-09 21:05:22 +0100 |
commit | b1e60e2015b81c285938ca569b66edda63d6533d (patch) | |
tree | 5181b92db2b2f605b3da04224d84a8b225f6d2ae | |
parent | ae45925d3a59ae3eb72d70e305d2c1dab5ef6d17 (diff) |
libcore changes to support ConnectionPool cache flushing
A set of observer / listener components for network
events.
Party A, e.g. the Android ConnectivityManager, can make
changes to network configuration that impacts the java
network objects (e.g. connection pools, caches, etc.).
Party B, e.g. Android libcore network components are
interested in network configuration changes.
The NetworkEventDispatcher enables Party A to communicate
with Party B without hardcoding their details. Additional
parties like B can be added.
Bug: 17314604
Change-Id: I175bdf28662bafcf0c91acb51a3da5cbc2b69086
3 files changed, 184 insertions, 0 deletions
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java new file mode 100644 index 0000000000..d1c7c21286 --- /dev/null +++ b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package libcore.net.event; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * A singleton used to dispatch network events to registered listeners. + */ +public class NetworkEventDispatcher { + + private static final NetworkEventDispatcher instance = new NetworkEventDispatcher(); + + private final List<NetworkEventListener> listeners = + new CopyOnWriteArrayList<NetworkEventListener>(); + + /** + * Returns the shared {@link NetworkEventDispatcher} instance. + */ + public static NetworkEventDispatcher getInstance() { + return instance; + } + + /** Visible for testing. Use {@link #getInstance()} instead. */ + protected NetworkEventDispatcher() { + } + + /** + * Registers a listener to be notified when network events occur. + * It can be deregistered using {@link #removeListener(NetworkEventListener)} + */ + public void addListener(NetworkEventListener toAdd) { + if (toAdd == null) { + throw new NullPointerException("toAdd == null"); + } + listeners.add(toAdd); + } + + /** + * De-registers a listener previously added with {@link #addListener(NetworkEventListener)}. If + * the listener was not previously registered this is a no-op. + */ + public void removeListener(NetworkEventListener toRemove) { + for (NetworkEventListener listener : listeners) { + if (listener == toRemove) { + listeners.remove(listener); + return; + } + } + } + + /** + * Notifies registered listeners of a network configuration change. + */ + public void onNetworkConfigurationChanged() { + for (NetworkEventListener listener : listeners) { + try { + listener.onNetworkConfigurationChanged(); + } catch (RuntimeException e) { + System.logI("Exception thrown during network event propagation", e); + } + } + } +} diff --git a/luni/src/main/java/libcore/net/event/NetworkEventListener.java b/luni/src/main/java/libcore/net/event/NetworkEventListener.java new file mode 100644 index 0000000000..73b9f88b88 --- /dev/null +++ b/luni/src/main/java/libcore/net/event/NetworkEventListener.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package libcore.net.event; + +/** + * A base class for objects interested in network events. + */ +public class NetworkEventListener { + + public void onNetworkConfigurationChanged() { + // no-op + } +} diff --git a/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java b/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java new file mode 100644 index 0000000000..dc32da69f0 --- /dev/null +++ b/luni/src/test/java/libcore/net/event/NetworkEventDispatcherTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package libcore.net.event; + +import junit.framework.TestCase; + +/** + * Tests for {@link NetworkEventDispatcher}. + */ +public class NetworkEventDispatcherTest extends TestCase { + + public void testGetInstance_isSingleton() { + assertSame(NetworkEventDispatcher.getInstance(), NetworkEventDispatcher.getInstance()); + } + + public void testAddListener_null() throws Exception { + NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {}; + try { + networkEventDispatcher.addListener(null); + fail(); + } catch (NullPointerException expected) { + } + } + + public void testOnNetworkConfigurationChanged_noListeners() throws Exception { + NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {}; + networkEventDispatcher.onNetworkConfigurationChanged(); + } + + public void testFireNetworkEvent_oneListener() throws Exception { + FakeNetworkEventListener listener = new FakeNetworkEventListener(); + NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {}; + networkEventDispatcher.addListener(listener); + + networkEventDispatcher.onNetworkConfigurationChanged(); + + listener.assertNetworkConfigurationChangedEvent(1); + } + + public void testRemoveEventListener() throws Exception { + FakeNetworkEventListener listener = new FakeNetworkEventListener(); + NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {}; + networkEventDispatcher.addListener(listener); + networkEventDispatcher.removeListener(listener); + + networkEventDispatcher.onNetworkConfigurationChanged(); + + listener.assertNetworkConfigurationChangedEvent(0); + } + + private static class FakeNetworkEventListener extends NetworkEventListener { + + private int networkConfigurationChangedCount; + + @Override + public void onNetworkConfigurationChanged() { + networkConfigurationChangedCount++; + } + + public void assertNetworkConfigurationChangedEvent(int expectedCount) { + assertEquals(expectedCount, networkConfigurationChangedCount); + } + } +} |