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
This commit is contained in:
@@ -543,7 +543,7 @@ public class IpClient extends StateMachine {
|
||||
}
|
||||
|
||||
private void startStateMachineUpdaters() {
|
||||
mObserverRegistry.registerObserver(mLinkObserver, getHandler());
|
||||
mObserverRegistry.registerObserverForNonblockingCallback(mLinkObserver);
|
||||
}
|
||||
|
||||
private void stopStateMachineUpdaters() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user