Merge download broadcast receivers

Previously, for all 4 states broadcast receivers were registered
separately. These have now been merged into one receiver.
This commit is contained in:
Dominik Schürmann 2016-07-29 01:56:49 +02:00
parent a31fb068ae
commit a442d539e4
4 changed files with 118 additions and 161 deletions

View File

@ -442,7 +442,7 @@ public class AppDetails extends AppCompatActivity {
refreshApkList(); refreshApkList();
supportInvalidateOptionsMenu(); supportInvalidateOptionsMenu();
if (DownloaderService.isQueuedOrActive(activeDownloadUrlString)) { if (DownloaderService.isQueuedOrActive(activeDownloadUrlString)) {
registerDownloaderReceivers(); registerDownloaderReceiver();
} }
visiblePackageName = app.packageName; visiblePackageName = app.packageName;
} }
@ -455,7 +455,7 @@ public class AppDetails extends AppCompatActivity {
if (headerFragment != null) { if (headerFragment != null) {
headerFragment.removeProgress(); headerFragment.removeProgress();
} }
unregisterDownloaderReceivers(); unregisterDownloaderReceiver();
} }
protected void onStop() { 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..."); Utils.debugLog(TAG, "Updating 'ignore updates', as it has changed since we started the activity...");
setIgnoreUpdates(app.packageName, app.ignoreAllUpdates, app.ignoreThisUpdate); setIgnoreUpdates(app.packageName, app.ignoreAllUpdates, app.ignoreThisUpdate);
} }
unregisterDownloaderReceivers(); unregisterDownloaderReceiver();
} }
private void unregisterDownloaderReceivers() { private void unregisterDownloaderReceiver() {
if (localBroadcastManager == null) { if (localBroadcastManager == null) {
return; return;
} }
localBroadcastManager.unregisterReceiver(startedReceiver); localBroadcastManager.unregisterReceiver(downloadReceiver);
localBroadcastManager.unregisterReceiver(progressReceiver);
localBroadcastManager.unregisterReceiver(completeReceiver);
localBroadcastManager.unregisterReceiver(interruptedReceiver);
} }
private void registerDownloaderReceivers() { private void registerDownloaderReceiver() {
if (activeDownloadUrlString != null) { // if a download is active if (activeDownloadUrlString != null) { // if a download is active
String url = activeDownloadUrlString; String url = activeDownloadUrlString;
localBroadcastManager.registerReceiver(startedReceiver, localBroadcastManager.registerReceiver(downloadReceiver,
DownloaderService.getIntentFilter(url, Downloader.ACTION_STARTED)); DownloaderService.getIntentFilter(url));
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));
} }
} }
private final BroadcastReceiver startedReceiver = new BroadcastReceiver() { private final BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (headerFragment != null) { switch (intent.getAction()) {
headerFragment.startProgress(); 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() { private final BroadcastReceiver installReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@ -682,7 +665,7 @@ public class AppDetails extends AppCompatActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
unregisterDownloaderReceivers(); unregisterDownloaderReceiver();
super.onDestroy(); super.onDestroy();
} }
@ -986,7 +969,7 @@ public class AppDetails extends AppCompatActivity {
private void startInstall(Apk apk) { private void startInstall(Apk apk) {
activeDownloadUrlString = apk.getUrl(); activeDownloadUrlString = apk.getUrl();
registerDownloaderReceivers(); registerDownloaderReceiver();
InstallManagerService.queue(this, app, apk); InstallManagerService.queue(this, app, apk);
} }

View File

@ -81,12 +81,6 @@ public class InstallManagerService extends Service {
*/ */
private static final HashMap<String, App> ACTIVE_APPS = new HashMap<>(3); private static final HashMap<String, App> 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<String, BroadcastReceiver[]> receivers = new HashMap<>(3);
private LocalBroadcastManager localBroadcastManager; private LocalBroadcastManager localBroadcastManager;
private NotificationManager notificationManager; private NotificationManager notificationManager;
@ -184,68 +178,50 @@ public class InstallManagerService extends Service {
localBroadcastManager.sendBroadcast(intent); 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) { private void registerDownloaderReceivers(String urlString, final NotificationCompat.Builder builder) {
BroadcastReceiver startedReceiver = new BroadcastReceiver() {
@Override BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
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() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
Uri downloadUri = intent.getData(); Uri downloadUri = intent.getData();
String urlString = downloadUri.toString(); 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); Utils.debugLog(TAG, "download completed of " + urlString + " to " + localApkUri);
registerInstallerReceivers(downloadUri);
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) { private void registerInstallerReceivers(Uri downloadUri) {

View File

@ -308,12 +308,14 @@ public class DownloaderService extends Service {
* Get a prepared {@link IntentFilter} for use for matching this service's action events. * Get a prepared {@link IntentFilter} for use for matching this service's action events.
* *
* @param urlString The full file URL to match. * @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); 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.addDataScheme(uri.getScheme());
intentFilter.addDataAuthority(uri.getHost(), String.valueOf(uri.getPort())); intentFilter.addDataAuthority(uri.getHost(), String.valueOf(uri.getPort()));
intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL); intentFilter.addDataPath(uri.getPath(), PatternMatcher.PATTERN_LITERAL);

View File

@ -242,44 +242,46 @@ public class SwapAppsView extends ListView implements
TextView statusInstalled; TextView statusInstalled;
TextView statusIncompatible; TextView statusIncompatible;
private final BroadcastReceiver downloadProgressReceiver = new BroadcastReceiver() { private final BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (progressView.getVisibility() != View.VISIBLE) { switch (intent.getAction()) {
showProgress(); 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();
} }
}; };
@ -307,14 +309,8 @@ public class SwapAppsView extends ListView implements
String urlString = apk.getUrl(); String urlString = apk.getUrl();
// TODO unregister receivers? or will they just die with this instance // TODO unregister receivers? or will they just die with this instance
localBroadcastManager.registerReceiver(appListViewResetReceiver, localBroadcastManager.registerReceiver(downloadReceiver,
DownloaderService.getIntentFilter(urlString, Downloader.ACTION_STARTED)); DownloaderService.getIntentFilter(urlString));
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));
// NOTE: Instead of continually unregistering and re-registering the observer // NOTE: Instead of continually unregistering and re-registering the observer
// (with a different URI), this could equally be done by only having one // (with a different URI), this could equally be done by only having one