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(); 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,67 +477,46 @@ 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) {
switch (intent.getAction()) {
case Downloader.ACTION_STARTED:
if (headerFragment != null) { if (headerFragment != null) {
headerFragment.startProgress(); headerFragment.startProgress();
} }
} break;
}; case Downloader.ACTION_PROGRESS:
private final BroadcastReceiver progressReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (headerFragment != null) { if (headerFragment != null) {
headerFragment.updateProgress(intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1), headerFragment.updateProgress(intent.getIntExtra(Downloader.EXTRA_BYTES_READ, -1),
intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1)); intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, -1));
} }
} break;
}; case Downloader.ACTION_COMPLETE:
// Starts the install process one the download is complete.
/**
* Starts the install process one the download is complete.
*/
private final BroadcastReceiver completeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
cleanUpFinishedDownload(); cleanUpFinishedDownload();
localBroadcastManager.registerReceiver(installReceiver, localBroadcastManager.registerReceiver(installReceiver,
Installer.getInstallIntentFilter(intent.getData())); Installer.getInstallIntentFilter(intent.getData()));
} break;
}; case Downloader.ACTION_INTERRUPTED:
private final BroadcastReceiver interruptedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) {
String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE)
+ " " + intent.getDataString(); + " " + intent.getDataString();
@ -547,6 +526,10 @@ public class AppDetails extends AppCompatActivity {
Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show();
} }
cleanUpFinishedDownload(); cleanUpFinishedDownload();
break;
default:
throw new RuntimeException("intent action not handled!");
}
} }
}; };
@ -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();
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)); File localFile = new File(intent.getStringExtra(Downloader.EXTRA_DOWNLOAD_PATH));
Uri localApkUri = Uri.fromFile(localFile); Uri localApkUri = Uri.fromFile(localFile);
Utils.debugLog(TAG, "download completed of " + urlString + " to " + localApkUri); Utils.debugLog(TAG, "download completed of " + urlString + " to " + localApkUri);
unregisterDownloaderReceivers(urlString); localBroadcastManager.unregisterReceiver(this);
registerInstallerReceivers(downloadUri); registerInstallerReceivers(downloadUri);
Apk apk = ACTIVE_APKS.get(urlString); Apk apk = ACTIVE_APKS.get(urlString);
InstallerService.install(context, localApkUri, downloadUri, apk); InstallerService.install(context, localApkUri, downloadUri, apk);
} break;
}; case Downloader.ACTION_INTERRUPTED:
BroadcastReceiver interruptedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String urlString = intent.getDataString();
removeFromActive(urlString); removeFromActive(urlString);
unregisterDownloaderReceivers(urlString); localBroadcastManager.unregisterReceiver(this);
cancelNotification(urlString); cancelNotification(urlString);
break;
default:
throw new RuntimeException("intent action not handled!");
}
} }
}; };
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

@ -241,9 +241,14 @@ 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) {
switch (intent.getAction()) {
case Downloader.ACTION_STARTED:
resetView();
break;
case Downloader.ACTION_PROGRESS:
if (progressView.getVisibility() != View.VISIBLE) { if (progressView.getVisibility() != View.VISIBLE) {
showProgress(); showProgress();
} }
@ -257,19 +262,11 @@ public class SwapAppsView extends ListView implements
} else { } else {
progressView.setIndeterminate(true); progressView.setIndeterminate(true);
} }
} break;
}; case Downloader.ACTION_COMPLETE:
private final BroadcastReceiver appListViewResetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
resetView(); resetView();
} break;
}; case Downloader.ACTION_INTERRUPTED:
private final BroadcastReceiver interruptedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) { if (intent.hasExtra(Downloader.EXTRA_ERROR_MESSAGE)) {
String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE) String msg = intent.getStringExtra(Downloader.EXTRA_ERROR_MESSAGE)
+ " " + intent.getDataString(); + " " + intent.getDataString();
@ -279,6 +276,11 @@ public class SwapAppsView extends ListView implements
Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show(); Toast.makeText(context, R.string.details_notinstalled, Toast.LENGTH_LONG).show();
} }
resetView(); resetView();
break;
default:
throw new RuntimeException("intent action not handled!");
}
} }
}; };
@ -306,14 +308,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