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 3b41f05d68)

Change-Id: If956addbf8e7b11b36a4b966de7fca00e8f362c1
This commit is contained in:
Hugo Benichi
2016-07-07 10:15:56 +09:00
committed by Lorenzo Colitti
parent 56260ed9cb
commit 301b09738a

View File

@@ -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<NetworkRequest, NetworkCallback> 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;
}