Hold a wake lock until downloads are finished
Cette révision appartient à :
Parent
0f372ba069
révision
a130506514
2 fichiers modifiés avec 67 ajouts et 17 suppressions
|
@ -28,6 +28,7 @@ import eu.kanade.mangafeed.util.DiskUtils;
|
|||
import eu.kanade.mangafeed.util.DynamicConcurrentMergeOperator;
|
||||
import rx.Observable;
|
||||
import rx.Subscription;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
import rx.subjects.BehaviorSubject;
|
||||
import rx.subjects.PublishSubject;
|
||||
|
@ -46,7 +47,8 @@ public class DownloadManager {
|
|||
private Subscription threadsNumberSubscription;
|
||||
|
||||
private DownloadQueue queue;
|
||||
private transient boolean isQueuePaused;
|
||||
private volatile boolean isQueuePaused;
|
||||
private volatile boolean isRunning;
|
||||
|
||||
public static final String PAGE_LIST_FILE = "index.json";
|
||||
|
||||
|
@ -54,9 +56,12 @@ public class DownloadManager {
|
|||
this.context = context;
|
||||
this.sourceManager = sourceManager;
|
||||
this.preferences = preferences;
|
||||
this.gson = new Gson();
|
||||
|
||||
gson = new Gson();
|
||||
queue = new DownloadQueue();
|
||||
|
||||
downloadsQueueSubject = PublishSubject.create();
|
||||
threadsNumber = BehaviorSubject.create();
|
||||
}
|
||||
|
||||
public void initializeSubscriptions() {
|
||||
|
@ -66,9 +71,6 @@ public class DownloadManager {
|
|||
if (threadsNumberSubscription != null && !threadsNumberSubscription.isUnsubscribed())
|
||||
threadsNumberSubscription.unsubscribe();
|
||||
|
||||
downloadsQueueSubject = PublishSubject.create();
|
||||
threadsNumber = BehaviorSubject.create();
|
||||
|
||||
threadsNumberSubscription = preferences.getDownloadTheadsObservable()
|
||||
.filter(n -> !isQueuePaused)
|
||||
.doOnNext(n -> isQueuePaused = (n == 0))
|
||||
|
@ -78,11 +80,19 @@ public class DownloadManager {
|
|||
.observeOn(Schedulers.newThread())
|
||||
.lift(new DynamicConcurrentMergeOperator<>(this::downloadChapter, threadsNumber))
|
||||
.onBackpressureBuffer()
|
||||
.subscribe(page -> {},
|
||||
e -> Timber.e(e.fillInStackTrace(), e.getMessage()));
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(finished -> {
|
||||
if (finished) {
|
||||
DownloadService.stop(context);
|
||||
}
|
||||
}, e -> Timber.e(e.fillInStackTrace(), e.getMessage()));
|
||||
|
||||
isRunning = true;
|
||||
}
|
||||
|
||||
public void destroySubscriptions() {
|
||||
isRunning = false;
|
||||
|
||||
if (downloadsSubscription != null && !downloadsSubscription.isUnsubscribed()) {
|
||||
downloadsSubscription.unsubscribe();
|
||||
downloadsSubscription = null;
|
||||
|
@ -104,6 +114,7 @@ public class DownloadManager {
|
|||
|
||||
if (!isChapterDownloaded(download)) {
|
||||
queue.add(download);
|
||||
if (isRunning) downloadsQueueSubject.onNext(download);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +150,7 @@ public class DownloadManager {
|
|||
}
|
||||
|
||||
// Download the entire chapter
|
||||
private Observable<Page> downloadChapter(Download download) {
|
||||
private Observable<Boolean> downloadChapter(Download download) {
|
||||
try {
|
||||
DiskUtils.createDirectory(download.directory);
|
||||
} catch (IOException e) {
|
||||
|
@ -164,7 +175,9 @@ public class DownloadManager {
|
|||
// Start downloading images, consider we can have downloaded images already
|
||||
.concatMap(page -> getDownloadedImage(page, download.source, download.directory))
|
||||
// Do after download completes
|
||||
.doOnCompleted(() -> onDownloadCompleted(download));
|
||||
.doOnCompleted(() -> onDownloadCompleted(download))
|
||||
.toList()
|
||||
.flatMap(pages -> Observable.just(areAllDownloadsFinished()));
|
||||
}
|
||||
|
||||
// Get downloaded image if exists, otherwise download it with the method below
|
||||
|
@ -229,9 +242,6 @@ public class DownloadManager {
|
|||
private void onDownloadCompleted(final Download download) {
|
||||
checkDownloadIsSuccessful(download);
|
||||
savePageList(download);
|
||||
if (areAllDownloadsFinished()) {
|
||||
DownloadService.stop(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDownloadIsSuccessful(final Download download) {
|
||||
|
@ -336,20 +346,27 @@ public class DownloadManager {
|
|||
threadsNumber.onNext(0);
|
||||
}
|
||||
|
||||
public void startDownloads() {
|
||||
public boolean startDownloads() {
|
||||
boolean hasPendingDownloads = false;
|
||||
if (downloadsSubscription == null || threadsNumberSubscription == null)
|
||||
initializeSubscriptions();
|
||||
|
||||
for (Download download : queue.get()) {
|
||||
if (download.getStatus() != Download.DOWNLOADED) {
|
||||
download.setStatus(Download.QUEUE);
|
||||
if (!hasPendingDownloads) hasPendingDownloads = true;
|
||||
downloadsQueueSubject.onNext(download);
|
||||
}
|
||||
}
|
||||
return hasPendingDownloads;
|
||||
}
|
||||
|
||||
public void stopDownloads() {
|
||||
destroySubscriptions();
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.content.Intent;
|
|||
import android.content.IntentFilter;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
|
@ -22,6 +23,7 @@ public class DownloadService extends Service {
|
|||
|
||||
@Inject DownloadManager downloadManager;
|
||||
|
||||
private PowerManager.WakeLock wakeLock;
|
||||
private Subscription networkChangeSubscription;
|
||||
|
||||
public static void start(Context context) {
|
||||
|
@ -37,11 +39,10 @@ public class DownloadService extends Service {
|
|||
super.onCreate();
|
||||
App.get(this).getComponent().inject(this);
|
||||
|
||||
// An initial event will be fired when subscribed.
|
||||
// This will cause the following download events to start or wait for a connection
|
||||
listenNetworkChanges();
|
||||
createWakeLock();
|
||||
|
||||
EventBus.getDefault().registerSticky(this);
|
||||
listenNetworkChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -54,6 +55,7 @@ public class DownloadService extends Service {
|
|||
EventBus.getDefault().unregister(this);
|
||||
networkChangeSubscription.unsubscribe();
|
||||
downloadManager.destroySubscriptions();
|
||||
destroyWakeLock();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -66,6 +68,8 @@ public class DownloadService extends Service {
|
|||
public void onEvent(DownloadChaptersEvent event) {
|
||||
EventBus.getDefault().removeStickyEvent(event);
|
||||
downloadManager.onDownloadChaptersEvent(event);
|
||||
if (downloadManager.isRunning())
|
||||
acquireWakeLock();
|
||||
}
|
||||
|
||||
private void listenNetworkChanges() {
|
||||
|
@ -73,11 +77,40 @@ public class DownloadService extends Service {
|
|||
networkChangeSubscription = ContentObservable.fromBroadcast(this, intentFilter)
|
||||
.subscribe(state -> {
|
||||
if (NetworkUtil.isNetworkConnected(this)) {
|
||||
downloadManager.startDownloads();
|
||||
// If there are no remaining downloads, destroy the service
|
||||
if (!downloadManager.startDownloads())
|
||||
stopSelf();
|
||||
else
|
||||
acquireWakeLock();
|
||||
} else {
|
||||
downloadManager.stopDownloads();
|
||||
releaseWakeLock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void createWakeLock() {
|
||||
wakeLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK, "DownloadService:WakeLock");
|
||||
}
|
||||
|
||||
private void destroyWakeLock() {
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
wakeLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void acquireWakeLock() {
|
||||
if (wakeLock != null && !wakeLock.isHeld()) {
|
||||
wakeLock.acquire();
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseWakeLock() {
|
||||
if (wakeLock != null && wakeLock.isHeld()) {
|
||||
wakeLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Référencer dans un nouveau ticket