OSDN Git Service

ConnectivityManager: use ConnectivityThread looper
authorHugo Benichi <hugobenichi@google.com>
Thu, 7 Jul 2016 01:15:56 +0000 (10:15 +0900)
committerHugo Benichi <hugobenichi@google.com>
Thu, 20 Oct 2016 23:54:34 +0000 (08:54 +0900)
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
Change-Id: I431afcee7c7155bd7bac23a2e1e97fd5d6520c74

core/java/android/net/ConnectivityManager.java

index db34124..0073dde 100644 (file)
@@ -2679,6 +2679,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 */
@@ -2790,24 +2791,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: {
@@ -2833,49 +2826,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);
@@ -2884,16 +2868,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;
     }