Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 791ee32a authored by Hugo Benichi's avatar Hugo Benichi Committed by Lorenzo Colitti
Browse files

DO NOT MERGE: ConnectivityManager: a simpler CallbackHandler

This patch simplifies CallbackHandler in the following way:
  - CallbackHandler directly uses the static references to
    sNetworkCallback and sCallbackRefCount. This allows to remove
    instance fields in CallbackHandler.
  - CallbackHandler does not have a reference to ConnectivityManager
    anymore
  - CallbackHandler.getObject() is now generic in a type-safe way.

Test: ConnectivityServiceTest passes
Bug: 28537383
Bug: 32130437

(cherry picked from commit d42650fa)

(cherry picked from commit 4983e558)

Change-Id: I4d0b2441b6af76bc56b19218210a2a381532a3c4
parent 81deef84
Loading
Loading
Loading
Loading
+31 −37
Original line number Original line Diff line number Diff line
@@ -2704,24 +2704,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);
            }
            }
@@ -2764,9 +2757,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;
@@ -2774,9 +2765,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;
@@ -2797,12 +2786,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();
                            }
                            }
                        }
                        }
@@ -2823,14 +2812,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");
@@ -2845,8 +2834,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);
            }
            }
        }
        }
    }
    }
@@ -2860,8 +2848,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;


@@ -2877,25 +2864,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;
    }
    }


    /**
    /**