From b9c247e2b12660dd0c38def9ba00141930b0e7d1 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 18 Apr 2018 10:50:09 +0200 Subject: [PATCH] if WifiManager fails to return netmask, directly query net interfaces Google broke returning the netmask somewhere around android-21. This could be done using more official APIs, but this reuses stuff that needs to be there anyway. closes #577 https://code.google.com/p/android/issues/detail?id=82477#c5 https://issuetracker.google.com/issues/37015180 --- app/src/main/java/org/fdroid/fdroid/FDroidApp.java | 4 +++- .../fdroid/fdroid/net/WifiStateChangeService.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java index d6321dfbb..c68f6737c 100644 --- a/app/src/main/java/org/fdroid/fdroid/FDroidApp.java +++ b/app/src/main/java/org/fdroid/fdroid/FDroidApp.java @@ -114,6 +114,8 @@ public class FDroidApp extends Application { public static volatile int networkState = ConnectivityMonitorService.FLAG_NET_UNAVAILABLE; + public static final SubnetUtils.SubnetInfo UNSET_SUBNET_INFO = new SubnetUtils("0.0.0.0/32").getInfo(); + private static volatile LongSparseArray lastWorkingMirrorArray = new LongSparseArray<>(1); private static volatile int numTries = Integer.MAX_VALUE; private static volatile int timeout = 10000; @@ -231,7 +233,7 @@ public class FDroidApp extends Application { public static void initWifiSettings() { port = 8888; ipAddressString = null; - subnetInfo = new SubnetUtils("0.0.0.0/32").getInfo(); + subnetInfo = UNSET_SUBNET_INFO; ssid = ""; bssid = ""; repo = new Repo(); diff --git a/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java b/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java index fcd62ad6c..d91100ea4 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java +++ b/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -121,6 +121,10 @@ public class WifiStateChangeService extends IntentService { } } } + if (FDroidApp.ipAddressString == null + || FDroidApp.subnetInfo == FDroidApp.UNSET_SUBNET_INFO) { + setIpInfoFromNetworkInterface(); + } } else if (wifiState == WifiManager.WIFI_STATE_DISABLED || wifiState == WifiManager.WIFI_STATE_DISABLING) { // try once to see if its a hotspot @@ -210,6 +214,16 @@ public class WifiStateChangeService extends IntentService { } } + /** + * Search for known Wi-Fi, Hotspot, and local network interfaces and get + * the IP Address info from it. This is necessary because network + * interfaces in Hotspot/AP mode do not show up in the regular + * {@link WifiManager} queries, and also on + * {@link android.os.Build.VERSION_CODES#LOLLIPOP Android 5.0} and newer, + * {@link WifiManager#getDhcpInfo()} returns an invalid netmask. + * + * @see netmask of WifiManager.getDhcpInfo() is always zero on Android 5.0 + */ private void setIpInfoFromNetworkInterface() { try { Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();