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 2329d045b..184c30bff 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -11,7 +11,6 @@ import android.content.pm.PackageInfo; import android.net.Uri; import android.os.IBinder; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.util.Log; @@ -213,7 +212,7 @@ public class InstallManagerService extends Service { long apkFileSize = apkFilePath.length(); if (!apkFilePath.exists() || apkFileSize < apk.size) { Utils.debugLog(TAG, "download " + urlString + " " + apkFilePath); - DownloaderService.queue(this, switchUrlToNewMirror(urlString, apk.repoId), apk.repoId, urlString); + DownloaderService.queueUsingRandomMirror(this, apk.repoId, urlString); } else if (ApkCache.apkIsCached(apkFilePath, apk)) { Utils.debugLog(TAG, "skip download, we have it, straight to install " + urlString + " " + apkFilePath); sendBroadcast(intent.getData(), Downloader.ACTION_STARTED, apkFilePath); @@ -221,7 +220,7 @@ public class InstallManagerService extends Service { } else { Utils.debugLog(TAG, "delete and download again " + urlString + " " + apkFilePath); apkFilePath.delete(); - DownloaderService.queue(this, switchUrlToNewMirror(urlString, apk.repoId), apk.repoId, urlString); + DownloaderService.queueUsingRandomMirror(this, apk.repoId, urlString); } return START_REDELIVER_INTENT; // if killed before completion, retry Intent @@ -234,24 +233,6 @@ public class InstallManagerService extends Service { localBroadcastManager.sendBroadcast(intent); } - /** - * Tries to return a version of {@code urlString} from a mirror, if there - * is an error, it just returns {@code urlString}. - * - * @see FDroidApp#getNewMirrorOnError(String, org.fdroid.fdroid.data.Repo) - */ - public String getNewMirrorOnError(@Nullable String urlString, long repoId) { - try { - return FDroidApp.getNewMirrorOnError(urlString, RepoProvider.Helper.findById(this, repoId)); - } catch (IOException e) { - return urlString; - } - } - - public String switchUrlToNewMirror(@Nullable String urlString, long repoId) { - return FDroidApp.switchUrlToNewMirror(urlString, RepoProvider.Helper.findById(this, repoId)); - } - /** * Check if any OBB files are available, and if so, download and install them. This * also deletes any obsolete OBB files, per the spec, since there can be only one @@ -310,13 +291,13 @@ public class InstallManagerService extends Service { } else if (Downloader.ACTION_INTERRUPTED.equals(action)) { localBroadcastManager.unregisterReceiver(this); } else if (Downloader.ACTION_CONNECTION_FAILED.equals(action)) { - DownloaderService.queue(context, getNewMirrorOnError(urlString, 0), 0, urlString); + DownloaderService.queueUsingDifferentMirror(context, 0, urlString); } else { throw new RuntimeException("intent action not handled!"); } } }; - DownloaderService.queue(this, switchUrlToNewMirror(obbUrlString, 0), 0, obbUrlString); + DownloaderService.queueUsingRandomMirror(this, 0, obbUrlString); localBroadcastManager.registerReceiver(downloadReceiver, DownloaderService.getIntentFilter(obbUrlString)); } @@ -337,7 +318,6 @@ public class InstallManagerService extends Service { Uri downloadUri = intent.getData(); String urlString = downloadUri.toString(); long repoId = intent.getLongExtra(Downloader.EXTRA_REPO_ID, 0); - String mirrorUrlString = intent.getStringExtra(Downloader.EXTRA_MIRROR_URL); switch (intent.getAction()) { case Downloader.ACTION_STARTED: @@ -357,7 +337,8 @@ public class InstallManagerService extends Service { File localFile = new File(intent.getStringExtra(Downloader.EXTRA_DOWNLOAD_PATH)); Uri localApkUri = Uri.fromFile(localFile); - Utils.debugLog(TAG, "download completed of " + mirrorUrlString + " to " + localApkUri); + Utils.debugLog(TAG, "download completed of " + + intent.getStringExtra(Downloader.EXTRA_MIRROR_URL) + " to " + localApkUri); appUpdateStatusManager.updateApk(urlString, AppUpdateStatusManager.Status.ReadyToInstall, null); localBroadcastManager.unregisterReceiver(this); @@ -374,7 +355,8 @@ public class InstallManagerService extends Service { break; case Downloader.ACTION_CONNECTION_FAILED: try { - String currentUrlString = FDroidApp.getNewMirrorOnError(mirrorUrlString, + String currentUrlString = FDroidApp.getNewMirrorOnError( + intent.getStringExtra(Downloader.EXTRA_MIRROR_URL), RepoProvider.Helper.findById(InstallManagerService.this, repoId)); DownloaderService.queue(context, currentUrlString, repoId, urlString); DownloaderService.setTimeout(FDroidApp.getTimeout()); diff --git a/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java b/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java index 0bfd358ba..19db341cb 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java +++ b/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java @@ -32,9 +32,11 @@ import android.os.Process; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.util.Log; +import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.ProgressListener; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; +import org.fdroid.fdroid.data.RepoProvider; import org.fdroid.fdroid.data.SanitizedFile; import org.fdroid.fdroid.installer.ApkCache; @@ -277,25 +279,54 @@ public class DownloaderService extends Service { *
* All notifications are sent as an {@link Intent} via local broadcasts to be received by * - * @param context this app's {@link Context} - * @param mirrorUrlString The URL to add to the download queue - * @param repoId the database ID number representing one repo - * @param canonicalUrl the URL used as the unique ID throughout F-Droid + * @param context this app's {@link Context} + * @param mirrorUrl The URL to add to the download queue + * @param repoId the database ID number representing one repo + * @param canonicalUrl the URL used as the unique ID throughout F-Droid * @see #cancel(Context, String) */ - public static void queue(Context context, String mirrorUrlString, long repoId, String canonicalUrl) { - if (TextUtils.isEmpty(mirrorUrlString)) { + public static void queue(Context context, String mirrorUrl, long repoId, String canonicalUrl) { + if (TextUtils.isEmpty(mirrorUrl)) { return; } - Utils.debugLog(TAG, "Preparing " + mirrorUrlString + " to go into the download queue"); + Utils.debugLog(TAG, "Preparing " + mirrorUrl + " to go into the download queue"); Intent intent = new Intent(context, DownloaderService.class); intent.setAction(ACTION_QUEUE); - intent.setData(Uri.parse(mirrorUrlString)); + intent.setData(Uri.parse(mirrorUrl)); intent.putExtra(Downloader.EXTRA_REPO_ID, repoId); intent.putExtra(Downloader.EXTRA_CANONICAL_URL, canonicalUrl); context.startService(intent); } + /** + * Add a package to the download queue, choosing a random mirror to + * download from. + * + * @param canonicalUrl the URL used as the unique ID throughout F-Droid, + * needed here to support canceling active downloads + */ + public static void queueUsingRandomMirror(Context context, long repoId, String canonicalUrl) { + String mirrorUrl = FDroidApp.switchUrlToNewMirror(canonicalUrl, + RepoProvider.Helper.findById(context, repoId)); + queue(context, mirrorUrl, repoId, canonicalUrl); + } + + /** + * Tries to return a version of {@code urlString} from a mirror, if there + * is an error, it just returns {@code urlString}. + * + * @see FDroidApp#getNewMirrorOnError(String, org.fdroid.fdroid.data.Repo) + */ + public static void queueUsingDifferentMirror(Context context, long repoId, String canonicalUrl) { + try { + String mirrorUrl = FDroidApp.getNewMirrorOnError(canonicalUrl, + RepoProvider.Helper.findById(context, repoId)); + queue(context, mirrorUrl, repoId, canonicalUrl); + } catch (IOException e) { + queue(context, canonicalUrl, repoId, canonicalUrl); + } + } + /** * Remove a URL to the download queue, even if it is currently downloading. *
@@ -345,10 +376,10 @@ public class DownloaderService extends Service { /** * Get a prepared {@link IntentFilter} for use for matching this service's action events. * - * @param urlString The full file URL to match. + * @param canonicalUrl the URL used as the unique ID for the specific package */ - public static IntentFilter getIntentFilter(String urlString) { - Uri uri = Uri.parse(urlString); + public static IntentFilter getIntentFilter(String canonicalUrl) { + Uri uri = Uri.parse(canonicalUrl); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Downloader.ACTION_STARTED); intentFilter.addAction(Downloader.ACTION_PROGRESS);