From fb3dcb293da4e25a0523ff5920af563f7846a7c7 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 24 May 2016 20:20:00 +0200 Subject: [PATCH 1/3] fix crash with Bluetooth on android-10 android.bluetooth.BluetoothSocket.isConnected() is only 14+ java.lang.NoSuchMethodError: android.bluetooth.BluetoothSocket.isConnected at org.fdroid.fdroid.net.bluetooth.BluetoothConnection.open(BluetoothConnection.java:37) at org.fdroid.fdroid.net.bluetooth.BluetoothClient.openConnection(BluetoothClient.java:31) at org.fdroid.fdroid.net.BluetoothDownloader.(BluetoothDownloader.java:30) at org.fdroid.fdroid.net.DownloaderFactory.create(DownloaderFactory.java:56) at org.fdroid.fdroid.RepoUpdater.downloadIndex(RepoUpdater.java:97) at org.fdroid.fdroid.RepoUpdater.update(RepoUpdater.java:131) at org.fdroid.fdroid.UpdateService.onHandleIntent(UpdateService.java:377) at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:130) at android.os.HandlerThread.run(HandlerThread.java:60) --- .../org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java b/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java index 55ebd042b..0eb4fbe89 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java +++ b/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothConnection.java @@ -34,7 +34,7 @@ public class BluetoothConnection { @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public void open() throws IOException { - if (!socket.isConnected()) { + if (Build.VERSION.SDK_INT >= 14 && !socket.isConnected()) { // Server sockets will already be connected when they are passed to us, // client sockets require us to call connect(). socket.connect(); From 2897dcb67e18e4d81c4b2a92ebffab2aabed7516 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 24 May 2016 20:52:45 +0200 Subject: [PATCH 2/3] fix crash when InstallManager is killed while actively downloading This is very related to #660 but this time, I can't see any other way to solve it but a null guard. I don't think it is possible to guarantee that the Downloader.ACTION_INTERRUPTED receiver will be unregistered since onDestroy() might not even be called. java.lang.NullPointerException at org.fdroid.fdroid.installer.InstallManagerService.removeFromActive(InstallManagerService.java:328) at org.fdroid.fdroid.installer.InstallManagerService.access$400(InstallManagerService.java:58) at org.fdroid.fdroid.installer.InstallManagerService$4.onReceive(InstallManagerService.java:212) at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297) at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46) at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5353) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:830) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:646) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method) --- .../fdroid/installer/InstallManagerService.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index 144eeef95..237a2584b 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -357,9 +357,18 @@ public class InstallManagerService extends Service { TEMP_HACK_APP_NAMES.put(urlString, app.name); // TODO delete me once InstallerService exists } + /** + * Remove the {@link App} and {@Apk} instances that are associated with + * {@code urlString} from the {@link Map} of active apps. This can be + * called after this service has been destroyed and recreated based on the + * {@link BroadcastReceiver}s, in which case {@code urlString} would not + * find anything in the active maps. + */ private static Apk removeFromActive(String urlString) { Apk apk = ACTIVE_APKS.remove(urlString); - ACTIVE_APPS.remove(apk.packageName); + if (apk != null) { + ACTIVE_APPS.remove(apk.packageName); + } return apk; } From 94f79a6438c7021db9c02003865c17f3a0da1718 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 24 May 2016 21:46:13 +0200 Subject: [PATCH 3/3] prevent crash caused by bad netmask given to WifiStateChangeService My guess is that is from IPv6, but those should be filtered out in this code before it gets to the crash point. Here's the stacktrace: java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) Caused by: java.lang.IllegalArgumentException: Value [64] not in range [0,32] at org.apache.commons.net.util.SubnetUtils.rangeCheck(SubnetUtils.java:339) at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:264) at org.apache.commons.net.util.SubnetUtils.(SubnetUtils.java:51) at org.fdroid.fdroid.net.WifiStateChangeService.setIpInfoFromNetworkInterface(WifiStateChangeService.java:222) at org.fdroid.fdroid.net.WifiStateChangeService.access$300(WifiStateChangeService.java:37) at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:99) at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:71) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) ... 4 more java.lang.IllegalArgumentException: Value [64] not in range [0,32] at org.apache.commons.net.util.SubnetUtils.rangeCheck(SubnetUtils.java:339) at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:264) at org.apache.commons.net.util.SubnetUtils.(SubnetUtils.java:51) at org.fdroid.fdroid.net.WifiStateChangeService.setIpInfoFromNetworkInterface(WifiStateChangeService.java:222) at org.fdroid.fdroid.net.WifiStateChangeService.access$300(WifiStateChangeService.java:37) at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:99) at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:71) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841) --- .../fdroid/fdroid/net/WifiStateChangeService.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 bd624427d..d0560a052 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java +++ b/app/src/main/java/org/fdroid/fdroid/net/WifiStateChangeService.java @@ -36,6 +36,12 @@ import java.util.Locale; * which is how it can be triggered by code, or it came in from the system * via {@link org.fdroid.fdroid.receiver.WifiStateChangeReceiver}, in * which case an instance of {@link NetworkInfo} is included. + * + * The work is done in a {@link Thread} so that new incoming {@code Intents} + * are not blocked by processing. A new {@code Intent} immediately nullifies + * the current state because it means that something about the wifi has + * changed. Having the {@code Thread} also makes it easy to kill work + * that is in progress. */ public class WifiStateChangeService extends IntentService { private static final String TAG = "WifiStateChangeService"; @@ -202,9 +208,15 @@ public class WifiStateChangeService extends IntentService { } // the following methods were not added until android-9/Gingerbread for (InterfaceAddress address : netIf.getInterfaceAddresses()) { + short networkPrefixLength = address.getNetworkPrefixLength(); + if (networkPrefixLength > 32) { + // something is giving a "/64" netmask, IPv6? + // java.lang.IllegalArgumentException: Value [64] not in range [0,32] + continue; + } if (inetAddress.equals(address.getAddress()) && !TextUtils.isEmpty(FDroidApp.ipAddressString)) { String cidr = String.format(Locale.ENGLISH, "%s/%d", - FDroidApp.ipAddressString, address.getNetworkPrefixLength()); + FDroidApp.ipAddressString, networkPrefixLength); FDroidApp.subnetInfo = new SubnetUtils(cidr).getInfo(); break; }