From 0164adc386cac98a48238584b0a213ace19cfa41 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Sun, 4 Oct 2015 11:01:02 +1100 Subject: [PATCH 1/2] Don't depend on Content-Length headers to download (Fixes #430) Instead, keep downloading until the `InputStream` returns -1. Also, required updates to the UI so that when the download size is not known, there is still a reasonable response to the user. Note that this still fails when using the Android download manager if the download attempts to get resumed, and the server did not send a Connection: close, Content-Length, or Transfer-Encoding: Chunked header. --- F-Droid/res/values/strings.xml | 7 +++++ F-Droid/src/org/fdroid/fdroid/AppDetails.java | 28 ++++++++++++------- .../src/org/fdroid/fdroid/UpdateService.java | 13 ++++++--- .../src/org/fdroid/fdroid/net/Downloader.java | 5 ++-- .../fdroid/views/swap/SwapAppsView.java | 2 ++ 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/F-Droid/res/values/strings.xml b/F-Droid/res/values/strings.xml index 16c41b048..5028c49bb 100644 --- a/F-Droid/res/values/strings.xml +++ b/F-Droid/res/values/strings.xml @@ -172,6 +172,13 @@ - Percentage complete (int between 0-100) --> Downloading\n%2$s / %3$s (%4$d%%) from\n%1$s + + + Downloading\n%2$s from\n%1$s Updating repositories Processing %2$s / %3$s (%4$d%%) from %1$s Connecting to\n%1$s diff --git a/F-Droid/src/org/fdroid/fdroid/AppDetails.java b/F-Droid/src/org/fdroid/fdroid/AppDetails.java index 1eacb86eb..5d7424405 100644 --- a/F-Droid/src/org/fdroid/fdroid/AppDetails.java +++ b/F-Droid/src/org/fdroid/fdroid/AppDetails.java @@ -1493,18 +1493,26 @@ public class AppDetails extends AppCompatActivity implements ProgressListener, A /** * Updates progress bar and captions to new values (in bytes). */ - public void updateProgress(long progress, long total) { - // Avoid division by zero and other weird values - if (progress < 0 || total <= 0) { + public void updateProgress(long bytesDownloaded, long totalBytes) { + if (bytesDownloaded < 0 || totalBytes == 0) { + // Avoid division by zero and other weird values return; } - long percent = progress * 100 / total; - setProgressVisible(true); - progressBar.setIndeterminate(false); - progressBar.setProgress((int) percent); - progressBar.setMax(100); - progressSize.setText(readableFileSize(progress) + " / " + readableFileSize(total)); - progressPercent.setText(Long.toString(percent) + " %"); + + if (totalBytes == -1) { + setProgressVisible(true); + progressBar.setIndeterminate(true); + progressSize.setText(readableFileSize(bytesDownloaded)); + progressPercent.setText(""); + } else { + long percent = bytesDownloaded * 100 / totalBytes; + setProgressVisible(true); + progressBar.setIndeterminate(false); + progressBar.setProgress((int) percent); + progressBar.setMax(100); + progressSize.setText(readableFileSize(bytesDownloaded) + " / " + readableFileSize(totalBytes)); + progressPercent.setText(Long.toString(percent) + " %"); + } } /** diff --git a/F-Droid/src/org/fdroid/fdroid/UpdateService.java b/F-Droid/src/org/fdroid/fdroid/UpdateService.java index cd5195384..bdde37883 100644 --- a/F-Droid/src/org/fdroid/fdroid/UpdateService.java +++ b/F-Droid/src/org/fdroid/fdroid/UpdateService.java @@ -209,12 +209,17 @@ public class UpdateService extends IntentService implements ProgressListener { String repoAddress = intent.getStringExtra(Downloader.EXTRA_ADDRESS); int downloadedSize = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1); + String downloadedSizeFriendly = Utils.getFriendlySize(downloadedSize); int totalSize = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1); int percent = (int) ((double) downloadedSize / totalSize * 100); - sendStatus(STATUS_INFO, - getString(R.string.status_download, repoAddress, - Utils.getFriendlySize(downloadedSize), - Utils.getFriendlySize(totalSize), percent)); + String message; + if (totalSize == -1) { + message = getString(R.string.status_download_unknown_size, repoAddress, downloadedSizeFriendly); + } else { + String totalSizeFriendly = Utils.getFriendlySize(totalSize); + message = getString(R.string.status_download, repoAddress, downloadedSizeFriendly, totalSizeFriendly, percent); + } + sendStatus(STATUS_INFO, message); } }; diff --git a/F-Droid/src/org/fdroid/fdroid/net/Downloader.java b/F-Droid/src/org/fdroid/fdroid/net/Downloader.java index 25084e603..3d987a606 100644 --- a/F-Droid/src/org/fdroid/fdroid/net/Downloader.java +++ b/F-Droid/src/org/fdroid/fdroid/net/Downloader.java @@ -154,11 +154,10 @@ public abstract class Downloader { throwExceptionIfInterrupted(); sendProgress(bytesRead, totalBytes); - while (bytesRead < totalBytes) { + while (true) { int count; - if (input.available()>0) { - + if (input.available() > 0) { int readLength = Math.min(input.available(), buffer.length); count = input.read(buffer, 0, readLength); } else { diff --git a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppsView.java b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppsView.java index f254fbcf8..6eb36fa28 100644 --- a/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppsView.java +++ b/F-Droid/src/org/fdroid/fdroid/views/swap/SwapAppsView.java @@ -293,6 +293,8 @@ public class SwapAppsView extends ListView implements progressView.setIndeterminate(false); progressView.setMax(100); progressView.setProgress(progress); + } else { + progressView.setIndeterminate(true); } } }; From 19ae4a76c261a49c5c7f625545467b9254f3b5dd Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Sun, 4 Oct 2015 11:24:39 +1100 Subject: [PATCH 2/2] Use existing byte-format function. Utils already contains a function to format bytes, removed duplicate function. --- F-Droid/src/org/fdroid/fdroid/AppDetails.java | 17 ++--------------- F-Droid/src/org/fdroid/fdroid/Utils.java | 2 +- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/F-Droid/src/org/fdroid/fdroid/AppDetails.java b/F-Droid/src/org/fdroid/fdroid/AppDetails.java index 5d7424405..4d2463f90 100644 --- a/F-Droid/src/org/fdroid/fdroid/AppDetails.java +++ b/F-Droid/src/org/fdroid/fdroid/AppDetails.java @@ -1502,7 +1502,7 @@ public class AppDetails extends AppCompatActivity implements ProgressListener, A if (totalBytes == -1) { setProgressVisible(true); progressBar.setIndeterminate(true); - progressSize.setText(readableFileSize(bytesDownloaded)); + progressSize.setText(Utils.getFriendlySize(bytesDownloaded)); progressPercent.setText(""); } else { long percent = bytesDownloaded * 100 / totalBytes; @@ -1510,24 +1510,11 @@ public class AppDetails extends AppCompatActivity implements ProgressListener, A progressBar.setIndeterminate(false); progressBar.setProgress((int) percent); progressBar.setMax(100); - progressSize.setText(readableFileSize(bytesDownloaded) + " / " + readableFileSize(totalBytes)); + progressSize.setText(Utils.getFriendlySize(bytesDownloaded) + " / " + Utils.getFriendlySize(totalBytes)); progressPercent.setText(Long.toString(percent) + " %"); } } - /** - * Converts a number of bytes to a human readable file size (eg 3.5 GiB). - * - * Based on http://stackoverflow.com/a/5599842 - */ - public String readableFileSize(long bytes) { - final String[] units = getResources().getStringArray(R.array.file_size_units); - if (bytes <= 0) return "0 " + units[0]; - int digitGroups = (int) (Math.log10(bytes) / Math.log10(1024)); - return new DecimalFormat("#,##0.#") - .format(bytes / Math.pow(1024, digitGroups)) + " " + units[digitGroups]; - } - /** * Shows or hides progress bar and related views. */ diff --git a/F-Droid/src/org/fdroid/fdroid/Utils.java b/F-Droid/src/org/fdroid/fdroid/Utils.java index 14db5651d..e5ccd595c 100644 --- a/F-Droid/src/org/fdroid/fdroid/Utils.java +++ b/F-Droid/src/org/fdroid/fdroid/Utils.java @@ -186,7 +186,7 @@ public final class Utils { } } - public static String getFriendlySize(int size) { + public static String getFriendlySize(long size) { double s = size; int i = 0; while (i < FRIENDLY_SIZE_FORMAT.length - 1 && s >= 1024) {