From 301b09738a5b164d55003bb1caa2f7b68d486754 Mon Sep 17 00:00:00 2001 From: Hugo Benichi Date: Thu, 7 Jul 2016 10:15:56 +0900 Subject: [PATCH] DO NOT MERGE: ConnectivityManager: use ConnectivityThread looper This patch removes the static singleton looper used by ConnectivityManager and instead uses the common ConnectivityThread. This allows to removes the static atomic counter used to track the number of registered NetworkCallback in ConnectivityManager, because the looper is not turned off anymore when no callbacks are registered. Also an overloaded version of sendRequestForNetwork is added taking as a new parameter a Handler. This will allow to overload various callback and request related API calls with user provided Handlers. Test: ConnectivityServiceTest passes Bug: 26749700 Bug: 28537383 Bug: 32130437 (cherry picked from commit 3b41f05d6803679795ba4fe1e1f5aea86dfd93b6) Change-Id: If956addbf8e7b11b36a4b966de7fca00e8f362c1 --- .../java/android/net/ConnectivityManager.java | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 780a9c8acf..51431ebfaf 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -2660,6 +2660,7 @@ public class ConnectivityManager { public static final int CALLBACK_IP_CHANGED = BASE + 7; /** @hide */ public static final int CALLBACK_RELEASED = BASE + 8; + // TODO: consider deleting CALLBACK_EXIT and shifting following enum codes down by 1. /** @hide */ public static final int CALLBACK_EXIT = BASE + 9; /** @hide obj = NetworkCapabilities, arg1 = seq number */ @@ -2771,24 +2772,16 @@ public class ConnectivityManager { break; } case CALLBACK_RELEASED: { - NetworkCallback callback = null; + final NetworkCallback callback; synchronized(sCallbacks) { callback = sCallbacks.remove(request); } - if (callback != null) { - synchronized(sCallbackRefCount) { - if (sCallbackRefCount.decrementAndGet() == 0) { - getLooper().quit(); - } - } - } else { + if (callback == null) { Log.e(TAG, "callback not found for RELEASED message"); } break; } case CALLBACK_EXIT: { - Log.d(TAG, "Listener quitting"); - getLooper().quit(); break; } case EXPIRE_LEGACY_REQUEST: { @@ -2814,49 +2807,40 @@ public class ConnectivityManager { } } - private void incCallbackHandlerRefCount() { - synchronized(sCallbackRefCount) { - if (sCallbackRefCount.incrementAndGet() == 1) { - // TODO: switch this to ConnectivityThread - HandlerThread callbackThread = new HandlerThread("ConnectivityManager"); - callbackThread.start(); - sCallbackHandler = new CallbackHandler(callbackThread.getLooper()); - } - } - } - - private void decCallbackHandlerRefCount() { - synchronized(sCallbackRefCount) { - if (sCallbackRefCount.decrementAndGet() == 0) { - sCallbackHandler.obtainMessage(CALLBACK_EXIT).sendToTarget(); - sCallbackHandler = null; + private CallbackHandler getHandler() { + synchronized (sCallbacks) { + if (sCallbackHandler == null) { + sCallbackHandler = new CallbackHandler(ConnectivityThread.getInstanceLooper()); } + return sCallbackHandler; } } static final HashMap sCallbacks = new HashMap<>(); - static final AtomicInteger sCallbackRefCount = new AtomicInteger(0); - static CallbackHandler sCallbackHandler = null; + static CallbackHandler sCallbackHandler; private final static int LISTEN = 1; private final static int REQUEST = 2; private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, - NetworkCallback networkCallback, int timeoutMs, int action, - int legacyType) { - if (networkCallback == null) { + NetworkCallback callback, int timeoutMs, int action, int legacyType) { + return sendRequestForNetwork(need, callback, getHandler(), timeoutMs, action, legacyType); + } + + private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, + NetworkCallback callback, Handler handler, int timeoutMs, int action, int legacyType) { + if (callback == null) { throw new IllegalArgumentException("null NetworkCallback"); } if (need == null && action != REQUEST) { throw new IllegalArgumentException("null NetworkCapabilities"); } - // TODO: throw an exception if networkCallback.networkRequest is not null. + // TODO: throw an exception if callback.networkRequest is not null. // http://b/20701525 final NetworkRequest request; try { - incCallbackHandlerRefCount(); synchronized(sCallbacks) { - Messenger messenger = new Messenger(sCallbackHandler); + Messenger messenger = new Messenger(handler); Binder binder = new Binder(); if (action == LISTEN) { request = mService.listenForNetwork(need, messenger, binder); @@ -2865,16 +2849,13 @@ public class ConnectivityManager { need, messenger, timeoutMs, binder, legacyType); } if (request != null) { - sCallbacks.put(request, networkCallback); + sCallbacks.put(request, callback); } - networkCallback.networkRequest = request; + callback.networkRequest = request; } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } - if (request == null) { - decCallbackHandlerRefCount(); - } return request; }