diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails.java b/app/src/main/java/org/fdroid/fdroid/AppDetails.java index 8bc60b6dc..5749dcbbf 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails.java @@ -442,7 +442,7 @@ public class AppDetails extends AppCompatActivity { refreshApkList(); supportInvalidateOptionsMenu(); if (DownloaderService.isQueuedOrActive(activeDownloadUrlString)) { - registerDownloaderReceivers(); + registerDownloaderReceiver(); } visiblePackageName = app.packageName; } @@ -455,7 +455,7 @@ public class AppDetails extends AppCompatActivity { if (headerFragment != null) { headerFragment.removeProgress(); } - unregisterDownloaderReceivers(); + unregisterDownloaderReceiver(); } protected void onStop() { @@ -477,79 +477,62 @@ public class AppDetails extends AppCompatActivity { Utils.debugLog(TAG, "Updating 'ignore updates', as it has changed since we started the activity..."); setIgnoreUpdates(app.packageName, app.ignoreAllUpdates, app.ignoreThisUpdate); } - unregisterDownloaderReceivers(); + unregisterDownloaderReceiver(); } - private void unregisterDownloaderReceivers() { + private void unregisterDownloaderReceiver() { if (localBroadcastManager == null) { return; } - localBroadcastManager.unregisterReceiver(startedReceiver); - localBroadcastManager.unregisterReceiver(progressReceiver); - localBroadcastManager.unregisterReceiver(completeReceiver); - localBroadcastManager.unregisterReceiver(interruptedReceiver); + localBroadcastManager.unregisterReceiver(downloadReceiver); } - private void registerDownloaderReceivers() { + private void registerDownloaderReceiver() { if (activeDownloadUrlString != null) { // if a download is active String url = activeDownloadUrlString; - localBroadcastManager.registerReceiver(startedReceiver, - DownloaderService.getIntentFilter(url, Downloader.ACTION_STARTED)); - localBroadcastManager.registerReceiver(progressReceiver, - DownloaderService.getIntentFilter(url, Downloader.ACTION_PROGRESS)); - localBroadcastManager.registerReceiver(completeReceiver, - DownloaderService.getIntentFilter(url, Downloader.ACTION_COMPLETE)); - localBroadcastManager.registerReceiver(interruptedReceiver, - DownloaderService.getIntentFilter(url, Downloader.ACTION_INTERRUPTED)); + localBroadcastManager.registerReceiver(downloadReceiver, + DownloaderService.getIntentFilter(url)); } } - private final BroadcastReceiver startedReceiver = new BroadcastReceiver() { + private final BroadcastReceiver downloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (headerFragment != null) { - headerFragment.startProgress(); + switch (intent.getAction()) { + case Downloader.ACTION_STARTED: + if (headerFragment != null) { + headerFragment.startProgress(); + } + break; + case Downloader.ACTION_PROGRESS: + if (headerFragment != null) { + headerFragment.updateProgress(intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1), + intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1)); + } + break; + case Downloader.ACTION_COMPLETE: + // Starts the install process one the download is complete. + cleanUpFinishedDownload(); + localBroadcastManager.registerReceiver(installReceiver, + Installer.getInstallIntentFilter(intent.getData())); + break; + case Downloader.ACTION_INTERRUPTED: + if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { + String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) + + " " + intent.getDataString(); + Toast.makeText(context, R.string.download_error, Toast.LENGTH_SHORT).show(); + Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); + } else { // user canceled + Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show(); + } + cleanUpFinishedDownload(); + break; + default: + throw new RuntimeException("intent action not handled!"); } } }; - private final BroadcastReceiver progressReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (headerFragment != null) { - headerFragment.updateProgress(intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1), - intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1)); - } - } - }; - - /** - * Starts the install process one the download is complete. - */ - private final BroadcastReceiver completeReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - cleanUpFinishedDownload(); - localBroadcastManager.registerReceiver(installReceiver, - Installer.getInstallIntentFilter(intent.getData())); - } - }; - - private final BroadcastReceiver interruptedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { - String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) - + " " + intent.getDataString(); - Toast.makeText(context, R.string.download_error, Toast.LENGTH_SHORT).show(); - Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); - } else { // user canceled - Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show(); - } - cleanUpFinishedDownload(); - } - }; - private final BroadcastReceiver installReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -682,7 +665,7 @@ public class AppDetails extends AppCompatActivity { @Override protected void onDestroy() { - unregisterDownloaderReceivers(); + unregisterDownloaderReceiver(); super.onDestroy(); } @@ -986,7 +969,7 @@ public class AppDetails extends AppCompatActivity { private void startInstall(Apk apk) { activeDownloadUrlString = apk.getUrl(); - registerDownloaderReceivers(); + registerDownloaderReceiver(); InstallManagerService.queue(this, app, apk); } 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 631c4edee..ff6c98e07 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -81,12 +81,6 @@ public class InstallManagerService extends Service { */ private static final HashMap ACTIVE_APPS = new HashMap<>(3); - /** - * The array of active {@link BroadcastReceiver}s for each active APK. The key is the - * download URL, as in {@link Apk#getUrl()} or {@code urlString}. - */ - private final HashMap receivers = new HashMap<>(3); - private LocalBroadcastManager localBroadcastManager; private NotificationManager notificationManager; @@ -184,68 +178,50 @@ public class InstallManagerService extends Service { localBroadcastManager.sendBroadcast(intent); } - private void unregisterDownloaderReceivers(String urlString) { - for (BroadcastReceiver receiver : receivers.get(urlString)) { - localBroadcastManager.unregisterReceiver(receiver); - } - } - private void registerDownloaderReceivers(String urlString, final NotificationCompat.Builder builder) { - BroadcastReceiver startedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - } - }; - BroadcastReceiver progressReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String urlString = intent.getDataString(); - int bytesRead = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); - int totalBytes = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); - builder.setProgress(totalBytes, bytesRead, false); - notificationManager.notify(urlString.hashCode(), builder.build()); - } - }; - BroadcastReceiver completeReceiver = new BroadcastReceiver() { + + BroadcastReceiver downloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Uri downloadUri = intent.getData(); String urlString = downloadUri.toString(); - File localFile = new File(intent.getStringExtra(Downloader.EXTRA_DOWNLOAD_PATH)); - Uri localApkUri = Uri.fromFile(localFile); - Utils.debugLog(TAG, "download completed of " + urlString + " to " + localApkUri); + switch (intent.getAction()) { + case Downloader.ACTION_STARTED: + // nothing to do + break; + case Downloader.ACTION_PROGRESS: + int bytesRead = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); + int totalBytes = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + builder.setProgress(totalBytes, bytesRead, false); + notificationManager.notify(urlString.hashCode(), builder.build()); + break; + case Downloader.ACTION_COMPLETE: + File localFile = new File(intent.getStringExtra(Downloader.EXTRA_DOWNLOAD_PATH)); + Uri localApkUri = Uri.fromFile(localFile); - unregisterDownloaderReceivers(urlString); - registerInstallerReceivers(downloadUri); + Utils.debugLog(TAG, "download completed of " + urlString + " to " + localApkUri); - Apk apk = ACTIVE_APKS.get(urlString); + localBroadcastManager.unregisterReceiver(this); + registerInstallerReceivers(downloadUri); - InstallerService.install(context, localApkUri, downloadUri, apk); + Apk apk = ACTIVE_APKS.get(urlString); + + InstallerService.install(context, localApkUri, downloadUri, apk); + break; + case Downloader.ACTION_INTERRUPTED: + removeFromActive(urlString); + localBroadcastManager.unregisterReceiver(this); + cancelNotification(urlString); + break; + default: + throw new RuntimeException("intent action not handled!"); + } } }; - BroadcastReceiver interruptedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String urlString = intent.getDataString(); - removeFromActive(urlString); - unregisterDownloaderReceivers(urlString); - cancelNotification(urlString); - } - }; - localBroadcastManager.registerReceiver(startedReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_STARTED)); - localBroadcastManager.registerReceiver(progressReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_PROGRESS)); - localBroadcastManager.registerReceiver(completeReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_COMPLETE)); - localBroadcastManager.registerReceiver(interruptedReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_INTERRUPTED)); - receivers.put(urlString, new BroadcastReceiver[]{ - startedReceiver, progressReceiver, completeReceiver, interruptedReceiver, - }); - + localBroadcastManager.registerReceiver(downloadReceiver, + DownloaderService.getIntentFilter(urlString)); } private void registerInstallerReceivers(Uri downloadUri) { 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 05da546c9..57588dd7c 100644 --- a/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java +++ b/app/src/main/java/org/fdroid/fdroid/net/DownloaderService.java @@ -308,12 +308,14 @@ 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 action {@link Downloader#ACTION_STARTED}, {@link Downloader#ACTION_PROGRESS}, - * {@link Downloader#ACTION_INTERRUPTED}, or {@link Downloader#ACTION_COMPLETE}, */ - public static IntentFilter getIntentFilter(String urlString, String action) { + public static IntentFilter getIntentFilter(String urlString) { Uri uri = Uri.parse(urlString); - IntentFilter intentFilter = new IntentFilter(action); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Downloader.ACTION_STARTED); + intentFilter.addAction(Downloader.ACTION_PROGRESS); + intentFilter.addAction(Downloader.ACTION_COMPLETE); + intentFilter.addAction(Downloader.ACTION_INTERRUPTED); intentFilter.addDataScheme(uri.getScheme()); intentFilter.addDataAuthority(uri.getHost(), String.valueOf(uri.getPort())); intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL); diff --git a/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java b/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java index aa930c15c..9c431146c 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java +++ b/app/src/main/java/org/fdroid/fdroid/views/swap/SwapAppsView.java @@ -241,44 +241,46 @@ public class SwapAppsView extends ListView implements TextView statusInstalled; TextView statusIncompatible; - private final BroadcastReceiver downloadProgressReceiver = new BroadcastReceiver() { + private final BroadcastReceiver downloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (progressView.getVisibility() != View.VISIBLE) { - showProgress(); + switch (intent.getAction()) { + case Downloader.ACTION_STARTED: + resetView(); + break; + case Downloader.ACTION_PROGRESS: + if (progressView.getVisibility() != View.VISIBLE) { + showProgress(); + } + int read = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); + int total = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); + if (total > 0) { + int progress = (int) ((double) read / total * 100); + progressView.setIndeterminate(false); + progressView.setMax(100); + progressView.setProgress(progress); + } else { + progressView.setIndeterminate(true); + } + break; + case Downloader.ACTION_COMPLETE: + resetView(); + break; + case Downloader.ACTION_INTERRUPTED: + if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { + String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) + + " " + intent.getDataString(); + Toast.makeText(context, R.string.download_error, Toast.LENGTH_SHORT).show(); + Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); + } else { // user canceled + Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show(); + } + resetView(); + break; + default: + throw new RuntimeException("intent action not handled!"); } - int read = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0); - int total = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0); - if (total > 0) { - int progress = (int) ((double) read / total * 100); - progressView.setIndeterminate(false); - progressView.setMax(100); - progressView.setProgress(progress); - } else { - progressView.setIndeterminate(true); - } - } - }; - private final BroadcastReceiver appListViewResetReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - resetView(); - } - }; - - private final BroadcastReceiver interruptedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { - String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) - + " " + intent.getDataString(); - Toast.makeText(context, R.string.download_error, Toast.LENGTH_SHORT).show(); - Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); - } else { // user canceled - Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show(); - } - resetView(); } }; @@ -306,14 +308,8 @@ public class SwapAppsView extends ListView implements String urlString = apk.getUrl(); // TODO unregister receivers? or will they just die with this instance - localBroadcastManager.registerReceiver(appListViewResetReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_STARTED)); - localBroadcastManager.registerReceiver(downloadProgressReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_PROGRESS)); - localBroadcastManager.registerReceiver(appListViewResetReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_COMPLETE)); - localBroadcastManager.registerReceiver(interruptedReceiver, - DownloaderService.getIntentFilter(urlString, Downloader.ACTION_INTERRUPTED)); + localBroadcastManager.registerReceiver(downloadReceiver, + DownloaderService.getIntentFilter(urlString)); // NOTE: Instead of continually unregistering and re-registering the observer // (with a different URI), this could equally be done by only having one