summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemi NGUYEN VAN <reminv@google.com>2019-01-29 16:46:48 +0900
committerRemi NGUYEN VAN <reminv@google.com>2019-01-29 17:09:01 +0900
commit7c7217bb19a0e0c4f10557fbf3e1cf9a14f774ec (patch)
tree7c428323ed88badcd4f10a8aea9fbbf69708f367
parenta887977c3e24b777e10ff0ae6e3617dac772a6c9 (diff)
Run IpClientLinkObserver on Binder thread
This restores previous behavior, where callbacks would not be called on the IpClient handler thread. Test: atest FrameworksNetTests NetworkStackTests Test: flashed, WiFi works Bug: 123062477 Change-Id: I3015566b0922d76ac7cf70579a1de3e033bf7b4a
-rw-r--r--src/android/net/ip/IpClient.java2
-rw-r--r--src/com/android/server/NetworkObserverRegistry.java34
-rw-r--r--tests/src/android/net/ip/IpClientTest.java2
3 files changed, 32 insertions, 6 deletions
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 612ebf7..4315d34 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -543,7 +543,7 @@ public class IpClient extends StateMachine {
}
private void startStateMachineUpdaters() {
- mObserverRegistry.registerObserver(mLinkObserver, getHandler());
+ mObserverRegistry.registerObserverForNonblockingCallback(mLinkObserver);
}
private void stopStateMachineUpdaters() {
diff --git a/src/com/android/server/NetworkObserverRegistry.java b/src/com/android/server/NetworkObserverRegistry.java
index 86e5e14..4f55779 100644
--- a/src/com/android/server/NetworkObserverRegistry.java
+++ b/src/com/android/server/NetworkObserverRegistry.java
@@ -24,8 +24,10 @@ import android.net.LinkAddress;
import android.net.RouteInfo;
import android.os.Handler;
import android.os.RemoteException;
+import android.util.Log;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -35,6 +37,7 @@ import java.util.concurrent.ConcurrentHashMap;
* all INetworkManagementEventObserver objects that have registered with it.
*/
public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub {
+ private static final String TAG = NetworkObserverRegistry.class.getSimpleName();
/**
* Constructs a new NetworkObserverRegistry.
@@ -53,7 +56,7 @@ public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub
netd.registerUnsolicitedEventListener(this);
}
- private final ConcurrentHashMap<NetworkObserver, Handler> mObservers =
+ private final ConcurrentHashMap<NetworkObserver, Optional<Handler>> mObservers =
new ConcurrentHashMap<>();
/**
@@ -61,7 +64,20 @@ public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub
* This method may be called on any thread.
*/
public void registerObserver(@NonNull NetworkObserver observer, @NonNull Handler handler) {
- mObservers.put(observer, handler);
+ if (handler == null) {
+ throw new IllegalArgumentException("handler must be non-null");
+ }
+ mObservers.put(observer, Optional.of(handler));
+ }
+
+ /**
+ * Registers the specified observer, and start sending callbacks to it.
+ *
+ * <p>This method must only be called with callbacks that are nonblocking, such as callbacks
+ * that only send a message to a StateMachine.
+ */
+ public void registerObserverForNonblockingCallback(@NonNull NetworkObserver observer) {
+ mObservers.put(observer, Optional.empty());
}
/**
@@ -80,9 +96,19 @@ public class NetworkObserverRegistry extends INetdUnsolicitedEventListener.Stub
private void invokeForAllObservers(@NonNull final NetworkObserverEventCallback callback) {
// ConcurrentHashMap#entrySet is weakly consistent: observers that were in the map before
// creation will be processed, those added during traversal may or may not.
- for (Map.Entry<NetworkObserver, Handler> entry : mObservers.entrySet()) {
+ for (Map.Entry<NetworkObserver, Optional<Handler>> entry : mObservers.entrySet()) {
final NetworkObserver observer = entry.getKey();
- entry.getValue().post(() -> callback.sendCallback(observer));
+ final Optional<Handler> handler = entry.getValue();
+ if (handler.isPresent()) {
+ handler.get().post(() -> callback.sendCallback(observer));
+ return;
+ }
+
+ try {
+ callback.sendCallback(observer);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Error sending callback to observer", e);
+ }
}
}
diff --git a/tests/src/android/net/ip/IpClientTest.java b/tests/src/android/net/ip/IpClientTest.java
index 40d510a..7e57d1e 100644
--- a/tests/src/android/net/ip/IpClientTest.java
+++ b/tests/src/android/net/ip/IpClientTest.java
@@ -129,7 +129,7 @@ public class IpClientTest {
verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false);
verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname);
ArgumentCaptor<NetworkObserver> arg = ArgumentCaptor.forClass(NetworkObserver.class);
- verify(mObserverRegistry, times(1)).registerObserver(arg.capture(), any());
+ verify(mObserverRegistry, times(1)).registerObserverForNonblockingCallback(arg.capture());
mObserver = arg.getValue();
reset(mObserverRegistry);
reset(mNetd);