Merge "ConnectivityManager: a simpler CallbackHandler"

This commit is contained in:
Hugo Benichi
2016-10-20 23:46:28 +00:00
committed by Android (Google) Code Review

View File

@@ -2709,24 +2709,17 @@ public class ConnectivityManager {
} }
private class CallbackHandler extends Handler { private class CallbackHandler extends Handler {
private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
private final AtomicInteger mRefCount;
private static final String TAG = "ConnectivityManager.CallbackHandler"; private static final String TAG = "ConnectivityManager.CallbackHandler";
private final ConnectivityManager mCm;
private static final boolean DBG = false; private static final boolean DBG = false;
CallbackHandler(Looper looper, HashMap<NetworkRequest, NetworkCallback>callbackMap, CallbackHandler(Looper looper) {
AtomicInteger refCount, ConnectivityManager cm) {
super(looper); super(looper);
mCallbackMap = callbackMap;
mRefCount = refCount;
mCm = cm;
} }
@Override @Override
public void handleMessage(Message message) { public void handleMessage(Message message) {
NetworkRequest request = (NetworkRequest) getObject(message, NetworkRequest.class); NetworkRequest request = getObject(message, NetworkRequest.class);
Network network = (Network) getObject(message, Network.class); Network network = getObject(message, Network.class);
if (DBG) { if (DBG) {
Log.d(TAG, whatToString(message.what) + " for network " + network); Log.d(TAG, whatToString(message.what) + " for network " + network);
} }
@@ -2769,9 +2762,7 @@ public class ConnectivityManager {
case CALLBACK_CAP_CHANGED: { case CALLBACK_CAP_CHANGED: {
NetworkCallback callback = getCallback(request, "CAP_CHANGED"); NetworkCallback callback = getCallback(request, "CAP_CHANGED");
if (callback != null) { if (callback != null) {
NetworkCapabilities cap = (NetworkCapabilities)getObject(message, NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
NetworkCapabilities.class);
callback.onCapabilitiesChanged(network, cap); callback.onCapabilitiesChanged(network, cap);
} }
break; break;
@@ -2779,9 +2770,7 @@ public class ConnectivityManager {
case CALLBACK_IP_CHANGED: { case CALLBACK_IP_CHANGED: {
NetworkCallback callback = getCallback(request, "IP_CHANGED"); NetworkCallback callback = getCallback(request, "IP_CHANGED");
if (callback != null) { if (callback != null) {
LinkProperties lp = (LinkProperties)getObject(message, LinkProperties lp = getObject(message, LinkProperties.class);
LinkProperties.class);
callback.onLinkPropertiesChanged(network, lp); callback.onLinkPropertiesChanged(network, lp);
} }
break; break;
@@ -2802,12 +2791,12 @@ public class ConnectivityManager {
} }
case CALLBACK_RELEASED: { case CALLBACK_RELEASED: {
NetworkCallback callback = null; NetworkCallback callback = null;
synchronized(mCallbackMap) { synchronized(sCallbacks) {
callback = mCallbackMap.remove(request); callback = sCallbacks.remove(request);
} }
if (callback != null) { if (callback != null) {
synchronized(mRefCount) { synchronized(sCallbackRefCount) {
if (mRefCount.decrementAndGet() == 0) { if (sCallbackRefCount.decrementAndGet() == 0) {
getLooper().quit(); getLooper().quit();
} }
} }
@@ -2828,14 +2817,14 @@ public class ConnectivityManager {
} }
} }
private Object getObject(Message msg, Class c) { private <T> T getObject(Message msg, Class<T> c) {
return msg.getData().getParcelable(c.getSimpleName()); return (T) msg.getData().getParcelable(c.getSimpleName());
} }
private NetworkCallback getCallback(NetworkRequest req, String name) { private NetworkCallback getCallback(NetworkRequest req, String name) {
NetworkCallback callback; NetworkCallback callback;
synchronized(mCallbackMap) { synchronized(sCallbacks) {
callback = mCallbackMap.get(req); callback = sCallbacks.get(req);
} }
if (callback == null) { if (callback == null) {
Log.e(TAG, "callback not found for " + name + " message"); Log.e(TAG, "callback not found for " + name + " message");
@@ -2850,8 +2839,7 @@ public class ConnectivityManager {
// TODO: switch this to ConnectivityThread // TODO: switch this to ConnectivityThread
HandlerThread callbackThread = new HandlerThread("ConnectivityManager"); HandlerThread callbackThread = new HandlerThread("ConnectivityManager");
callbackThread.start(); callbackThread.start();
sCallbackHandler = new CallbackHandler(callbackThread.getLooper(), sCallbackHandler = new CallbackHandler(callbackThread.getLooper());
sNetworkCallback, sCallbackRefCount, this);
} }
} }
} }
@@ -2865,8 +2853,7 @@ public class ConnectivityManager {
} }
} }
static final HashMap<NetworkRequest, NetworkCallback> sNetworkCallback = static final HashMap<NetworkRequest, NetworkCallback> sCallbacks = new HashMap<>();
new HashMap<NetworkRequest, NetworkCallback>();
static final AtomicInteger sCallbackRefCount = new AtomicInteger(0); static final AtomicInteger sCallbackRefCount = new AtomicInteger(0);
static CallbackHandler sCallbackHandler = null; static CallbackHandler sCallbackHandler = null;
@@ -2882,25 +2869,32 @@ public class ConnectivityManager {
if (need == null && action != REQUEST) { if (need == null && action != REQUEST) {
throw new IllegalArgumentException("null NetworkCapabilities"); throw new IllegalArgumentException("null NetworkCapabilities");
} }
// TODO: throw an exception if networkCallback.networkRequest is not null.
// http://b/20701525
final NetworkRequest request;
try { try {
incCallbackHandlerRefCount(); incCallbackHandlerRefCount();
synchronized(sNetworkCallback) { synchronized(sCallbacks) {
Messenger messenger = new Messenger(sCallbackHandler);
Binder binder = new Binder();
if (action == LISTEN) { if (action == LISTEN) {
networkCallback.networkRequest = mService.listenForNetwork(need, request = mService.listenForNetwork(need, messenger, binder);
new Messenger(sCallbackHandler), new Binder());
} else { } else {
networkCallback.networkRequest = mService.requestNetwork(need, request = mService.requestNetwork(
new Messenger(sCallbackHandler), timeoutMs, new Binder(), legacyType); need, messenger, timeoutMs, binder, legacyType);
} }
if (networkCallback.networkRequest != null) { if (request != null) {
sNetworkCallback.put(networkCallback.networkRequest, networkCallback); sCallbacks.put(request, networkCallback);
} }
networkCallback.networkRequest = request;
} }
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} }
if (networkCallback.networkRequest == null) decCallbackHandlerRefCount(); if (request == null) {
return networkCallback.networkRequest; decCallbackHandlerRefCount();
}
return request;
} }
/** /**