Merge branch 'install-receiver' into 'master'

Merge download broadcast receivers

Previously, for all 4 states broadcast receivers were registered separately. These have now been merged into one receiver. IMHO this makes the code more readable and structured.

See merge request !368
This commit is contained in:
Daniel Martí 2016-07-31 17:08:56 +00:00
commit c61a055ea8
4 changed files with 118 additions and 161 deletions

View File

@ -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);
}

View File

@ -81,12 +81,6 @@ public class InstallManagerService extends Service {
*/
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 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) {

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.
*
* @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);

View File

@ -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