diff --git a/app/src/main/java/org/fdroid/fdroid/Utils.java b/app/src/main/java/org/fdroid/fdroid/Utils.java index d44231436..52a8b5441 100644 --- a/app/src/main/java/org/fdroid/fdroid/Utils.java +++ b/app/src/main/java/org/fdroid/fdroid/Utils.java @@ -417,13 +417,29 @@ public final class Utils { byte[] mdbytes = md.digest(); return toHexString(mdbytes).toLowerCase(Locale.ENGLISH); - } catch (IOException | NoSuchAlgorithmException e) { + } catch (IOException e) { + // The annoyance (potentially) caused by miscellaneous filesystem corruption results in + // F-Droid constantly popping up crash reports when F-Droid isn't even open. As such this + // exception-message-parsing-and-throwing-a-new-ignorable-exception-hackery is probably + // warranted. See https://www.gitlab.com/fdroid/fdroidclient/issues/855 for more detail. + if (e.getMessage().contains("read failed: EIO (I/O error)")) { + throw new PotentialFilesystemCorruptionException(e); + } + + throw new IllegalArgumentException(e); + } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } finally { closeQuietly(fis); } } + public static class PotentialFilesystemCorruptionException extends IllegalArgumentException { + public PotentialFilesystemCorruptionException(IOException e) { + super(e); + } + } + /** * Computes the base 16 representation of the byte array argument. * diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java index 6dcc83e33..5b2aaec29 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java +++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProviderService.java @@ -11,12 +11,16 @@ import android.net.Uri; import android.os.Process; import android.support.annotation.Nullable; import android.util.Log; - +import android.widget.Toast; import org.acra.ACRA; import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.Hasher; +import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Schema.InstalledAppTable; +import rx.functions.Action1; +import rx.schedulers.Schedulers; +import rx.subjects.PublishSubject; import java.io.File; import java.io.FilenameFilter; @@ -25,10 +29,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import rx.functions.Action1; -import rx.schedulers.Schedulers; -import rx.subjects.PublishSubject; - /** * Handles all updates to {@link InstalledAppProvider}, whether checking the contents * versus what Android says is installed, or processing {@link Intent}s that come @@ -76,12 +76,12 @@ public class InstalledAppProviderService extends IntentService { .subscribeOn(Schedulers.newThread()) .debounce(3, TimeUnit.SECONDS) .subscribe(new Action1() { - @Override - public void call(String packageName) { - Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views)."); - getContentResolver().notifyChange(AppProvider.getContentUri(), null); - getContentResolver().notifyChange(ApkProvider.getContentUri(), null); - } + @Override + public void call(String packageName) { + Utils.debugLog(TAG, "Notifying content providers (so they can update the relevant views)."); + getContentResolver().notifyChange(AppProvider.getContentUri(), null); + getContentResolver().notifyChange(ApkProvider.getContentUri(), null); + } }); // ...alternatively, this non-debounced version will instantly emit an event about the @@ -249,6 +249,15 @@ public class InstalledAppProviderService extends IntentService { } insertAppIntoDb(this, packageInfo, hashType, hash); + } catch (Utils.PotentialFilesystemCorruptionException e) { + String msg = getString(R.string.installed_app__file_corrupt, apk.getAbsolutePath()); + Toast.makeText(this, msg, Toast.LENGTH_LONG).show(); + Log.e(TAG, "Encountered potential filesystem corruption, or other unknown " + + "problem when calculating hash of " + apk.getAbsolutePath() + ". " + + "It is unlikely F-Droid can do anything about this, and this " + + "likely happened in the background. As such, we will continue without " + + "interrupting the user by asking them to send a crash report."); + return; } catch (IllegalArgumentException e) { Utils.debugLog(TAG, e.getMessage()); ACRA.getErrorReporter().handleException(e, false); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ab5e19c1c..d7f811eaf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -93,6 +93,7 @@ This often occurs with apps installed via Google Play or other sources, if they Updates ignored for Version %1$s + F-Droid received EIO error: %s is probably corrupt! Download Download all updates