add method to check if a URL is being handled by DownloaderService
This also saves the activeDownloadUrlString per packageName. Both are necessary so that AppDetails can accurately display the current state of a background download. Saving this per-packageName allows there to be multiple active downloads in the background, then when people move around AppDetails, it'll restore the progress meter and button state when coming back to the app that they clicked install on. By definition, there is just one DownloaderService enforced by Android with a single active Downloader instance enforced by the DownloaderService. That means using a static variable maps directly to those conditions and provides a really simple, implementation, especially compared to what would have to happen to do it via messages from the thread and any Activities. If this ends up blocking testing or something, it can always be changed when someone implements those tests.
This commit is contained in:
parent
49635c224d
commit
721d4a300a
@ -79,6 +79,7 @@ import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
|||||||
|
|
||||||
import org.fdroid.fdroid.Utils.CommaSeparatedList;
|
import org.fdroid.fdroid.Utils.CommaSeparatedList;
|
||||||
import org.fdroid.fdroid.compat.PackageManagerCompat;
|
import org.fdroid.fdroid.compat.PackageManagerCompat;
|
||||||
|
import org.fdroid.fdroid.compat.PreferencesCompat;
|
||||||
import org.fdroid.fdroid.data.Apk;
|
import org.fdroid.fdroid.data.Apk;
|
||||||
import org.fdroid.fdroid.data.ApkProvider;
|
import org.fdroid.fdroid.data.ApkProvider;
|
||||||
import org.fdroid.fdroid.data.App;
|
import org.fdroid.fdroid.data.App;
|
||||||
@ -428,7 +429,9 @@ public class AppDetails extends AppCompatActivity {
|
|||||||
refreshApkList();
|
refreshApkList();
|
||||||
refreshHeader();
|
refreshHeader();
|
||||||
supportInvalidateOptionsMenu();
|
supportInvalidateOptionsMenu();
|
||||||
registerDownloaderReceivers();
|
if (DownloaderService.isQueuedOrActive(activeDownloadUrlString)) {
|
||||||
|
registerDownloaderReceivers();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -448,6 +451,10 @@ public class AppDetails extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
// save the active URL for this app in case we come back
|
||||||
|
PreferencesCompat.apply(getPreferences(MODE_PRIVATE)
|
||||||
|
.edit()
|
||||||
|
.putString(getPackageNameFromIntent(getIntent()), activeDownloadUrlString));
|
||||||
if (app != null && (app.ignoreAllUpdates != startingIgnoreAll
|
if (app != null && (app.ignoreAllUpdates != startingIgnoreAll
|
||||||
|| app.ignoreThisUpdate != startingIgnoreThis)) {
|
|| app.ignoreThisUpdate != startingIgnoreThis)) {
|
||||||
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...");
|
||||||
@ -569,6 +576,14 @@ public class AppDetails extends AppCompatActivity {
|
|||||||
Utils.debugLog(TAG, "Getting application details for " + packageName);
|
Utils.debugLog(TAG, "Getting application details for " + packageName);
|
||||||
App newApp = null;
|
App newApp = null;
|
||||||
|
|
||||||
|
String urlString = getPreferences(MODE_PRIVATE).getString(packageName, null);
|
||||||
|
if (DownloaderService.isQueuedOrActive(urlString)) {
|
||||||
|
activeDownloadUrlString = urlString;
|
||||||
|
} else {
|
||||||
|
// this URL is no longer active, remove it
|
||||||
|
PreferencesCompat.apply(getPreferences(MODE_PRIVATE).edit().remove(packageName));
|
||||||
|
}
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(packageName)) {
|
if (!TextUtils.isEmpty(packageName)) {
|
||||||
newApp = AppProvider.Helper.findByPackageName(getContentResolver(), packageName);
|
newApp = AppProvider.Helper.findByPackageName(getContentResolver(), packageName);
|
||||||
}
|
}
|
||||||
|
@ -73,11 +73,11 @@ public class DownloaderService extends Service {
|
|||||||
private static final String ACTION_CANCEL = "org.fdroid.fdroid.net.DownloaderService.action.CANCEL";
|
private static final String ACTION_CANCEL = "org.fdroid.fdroid.net.DownloaderService.action.CANCEL";
|
||||||
|
|
||||||
private volatile Looper serviceLooper;
|
private volatile Looper serviceLooper;
|
||||||
private volatile ServiceHandler serviceHandler;
|
private static volatile ServiceHandler serviceHandler;
|
||||||
private volatile Downloader downloader;
|
private static volatile Downloader downloader;
|
||||||
private LocalBroadcastManager localBroadcastManager;
|
private LocalBroadcastManager localBroadcastManager;
|
||||||
|
|
||||||
private final HashMap<String, Integer> queueWhats = new HashMap<String, Integer>();
|
private static final HashMap<String, Integer> QUEUE_WHATS = new HashMap<String, Integer>();
|
||||||
private int what;
|
private int what;
|
||||||
|
|
||||||
private final class ServiceHandler extends Handler {
|
private final class ServiceHandler extends Handler {
|
||||||
@ -117,7 +117,7 @@ public class DownloaderService extends Service {
|
|||||||
}
|
}
|
||||||
if (ACTION_CANCEL.equals(intent.getAction())) {
|
if (ACTION_CANCEL.equals(intent.getAction())) {
|
||||||
Log.i(TAG, "Removed " + intent);
|
Log.i(TAG, "Removed " + intent);
|
||||||
Integer what = queueWhats.remove(uriString);
|
Integer what = QUEUE_WHATS.remove(uriString);
|
||||||
if (what != null && serviceHandler.hasMessages(what)) {
|
if (what != null && serviceHandler.hasMessages(what)) {
|
||||||
// the URL is in the queue, remove it
|
// the URL is in the queue, remove it
|
||||||
serviceHandler.removeMessages(what);
|
serviceHandler.removeMessages(what);
|
||||||
@ -134,8 +134,8 @@ public class DownloaderService extends Service {
|
|||||||
msg.obj = intent;
|
msg.obj = intent;
|
||||||
msg.what = what++;
|
msg.what = what++;
|
||||||
serviceHandler.sendMessage(msg);
|
serviceHandler.sendMessage(msg);
|
||||||
Log.i(TAG, "queueWhats.put(" + uriString + ", " + msg.what);
|
Log.i(TAG, "QUEUE_WHATS.put(" + uriString + ", " + msg.what);
|
||||||
queueWhats.put(uriString, msg.what);
|
QUEUE_WHATS.put(uriString, msg.what);
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "Received Intent with unknown action: " + intent);
|
Log.e(TAG, "Received Intent with unknown action: " + intent);
|
||||||
}
|
}
|
||||||
@ -170,7 +170,7 @@ public class DownloaderService extends Service {
|
|||||||
* the same DownloaderService, but it will not hold up anything else.
|
* the same DownloaderService, but it will not hold up anything else.
|
||||||
* When all requests have been handled, the DownloaderService stops itself,
|
* When all requests have been handled, the DownloaderService stops itself,
|
||||||
* so you should not ever call {@link #stopSelf}.
|
* so you should not ever call {@link #stopSelf}.
|
||||||
* <p>
|
* <p/>
|
||||||
* Downloads are put into subdirectories based on hostname/port of each repo
|
* Downloads are put into subdirectories based on hostname/port of each repo
|
||||||
* to prevent files with the same names from conflicting. Each repo enforces
|
* to prevent files with the same names from conflicting. Each repo enforces
|
||||||
* unique APK file names on the server side.
|
* unique APK file names on the server side.
|
||||||
@ -260,6 +260,21 @@ public class DownloaderService extends Service {
|
|||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a URL is waiting in the queue for downloading or if actively
|
||||||
|
* being downloaded. This is useful for checking whether to re-register
|
||||||
|
* {@link android.content.BroadcastReceiver}s in
|
||||||
|
* {@link android.app.Activity#onResume()}
|
||||||
|
*/
|
||||||
|
public static boolean isQueuedOrActive(String urlString) {
|
||||||
|
if (TextUtils.isEmpty(urlString)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Integer what = QUEUE_WHATS.get(urlString);
|
||||||
|
return (what != null && serviceHandler.hasMessages(what))
|
||||||
|
|| (downloader != null && TextUtils.equals(urlString, downloader.sourceUrl.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user