[Replicant] [PATCH v2] Fix "RepWifi connection not correctly reported to userspace apps" Issue #1792.

Fil fil.bergamo at riseup.net
Fri Aug 4 23:17:57 UTC 2017


When a WiFi connection is established using an external dongle via the
RepWifi app, although it's perfectly working, the framework still
presents the WiFi connection as disabled or disconnected to the
user-space apps.
This misleads apps that rely on this mechanism, so that they prevent the
user from doing network-related tasks.
This patch solves the issue by modifying getActiveNetworkInfo() method
in ConnectivityService.java, adding a basic mechanism to check if the
WiFi interface is connected.
java.net.NetworkInterface.getByName() is used to look for either
"wlan0" (RepWifi) or "rndis0"(Tethering).
If any one of the two interfaces is present, getInetAddresses() is
called on it, to see if it has any IP address.
If the interface has an IP address in the "local" range (e.g.
192.168.x.x), then it is considered to be connected. So an instance of
android.net.NetworkInfo is created, and its state is set as "Connected".
Finally, that instance gets returned to the caller.
The result should be so that user-space apps are now able to "see" the
internet connection made via RepWifi or via reverse tethering.

Changes since v1:
	- No changes to the framework's public API
	- All code inside the ConnectivityService class
	- No external shell commands involved, all is pure Java.

Signed-off-by: Fil Bergamo <fil.bergamo at riseup.net>
---
 .../com/android/server/ConnectivityService.java    | 68
++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git
a/services/core/java/com/android/server/ConnectivityService.java
b/services/core/java/com/android/server/ConnectivityService.java
index 1489fd8713a..fadc4f4f914 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -145,11 +145,13 @@ import java.io.IOException;
 import java.io.PrintWriter;
 import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.NetworkInterface;
 import java.net.UnknownHostException;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.SortedSet;
@@ -1017,9 +1019,75 @@ public class ConnectivityService extends
IConnectivityManager.Stub
         final int uid = Binder.getCallingUid();
         NetworkState state = getUnfilteredActiveNetworkState(uid);
         NetworkInfo ni = getFilteredNetworkInfo(state.networkInfo,
state.linkProperties, uid);
+
+        // TODO RepWifi extension. Remove when a low-level, long-lived
solution is found.
+        if (ni == null) {
+            ni = getNetworkInfoByInterfaceName(IFACE_NAME_WIFI);
+        }
+        if (ni == null) {
+            ni = getNetworkInfoByInterfaceName(IFACE_NAME_TETHER);
+        }
+                
         maybeLogBlockedNetworkInfo(ni, uid);
         return ni;
     }
+    
+    // TODO RepWifi extension. Remove when a low-level, long-lived
solution is found.
+    private static final String IFACE_NAME_WIFI = "wlan0";
+    private static final String IFACE_NAME_TETHER = "rndis0";
+    private NetworkInfo getNetworkInfoByInterfaceName(String ifname) {
+        try {
+
+            int type = 0;
+            String typeName = null;
+
+            if (ifname == IFACE_NAME_WIFI) {
+                type = ConnectivityManager.TYPE_WIFI;
+                typeName = "WIFI";
+
+            } else if (ifname == IFACE_NAME_TETHER) {
+                type = ConnectivityManager.TYPE_ETHERNET;
+                typeName = "ETHERNET";
+
+            } else {
+                return null;
+            }
+
+            NetworkInterface nifRep =
NetworkInterface.getByName(ifname);
+            if (nifRep == null) {
+                return null;
+            }
+
+            Enumeration<InetAddress> ads = nifRep.getInetAddresses();
+            if (ads == null) {
+                return null;
+            }
+
+            while (ads.hasMoreElements()) {
+
+                InetAddress a = ads.nextElement();
+
+                if (a.getHostAddress() != null &&
a.isSiteLocalAddress()) {
+                    // if the interface has a valid IP address in the
range of a
+                    // local network we consider it is connected to an
AP.
+                    NetworkInfo ninfo = new NetworkInfo(type, 0,
typeName, "");
+                    ninfo.setDetailedState(DetailedState.CONNECTED,
null, null);
+                    ninfo.setIsAvailable(true);
+                    return ninfo;
+                }
+
+            }
+
+            // if we reached here, the interface has no valid address
+            return null;
+
+        } catch (Exception e) {
+            // Exceptions are suppressed to avoid crashing the
surrounding system service.
+            // This is only a best-effort hack. 
+            return null;
+        }
+
+    }
 
     @Override
     public Network getActiveNetwork() {
-- 
2.11.0

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/replicant/attachments/20170805/235c10c5/attachment.asc>


More information about the Replicant mailing list