Show remaining time in download notification

This commit is contained in:
seven332 committed 2016-03-03 20:18:37 +08:00
1 parent d32168ff02
commit 3770f74709
12 files changed
+128 -31

No files matched your search

@@ -31,8 +31,12 @@ public class DownloadInfo {
public int state = STATE_NONE;
// byte/second, -1 for can't get speed now
public long speed;
// Remain time millis
public long remaining;
// -1 for unknown
public int download = 0;
public int finished = 0;
// -1 for unknown
public int downloaded = 0;
// -1 for unknown
public int total = -1;
// -1 for unknown
@@ -30,8 +30,10 @@ import com.hippo.ehviewer.spider.SpiderQueen;
import com.hippo.image.Image;
import com.hippo.yorozuya.ConcurrentPool;
import com.hippo.yorozuya.IntList;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.ObjectUtils;
import com.hippo.yorozuya.SimpleHandler;
import com.hippo.yorozuya.sparse.SparseIJArray;
import java.util.Collections;
import java.util.Comparator;
@@ -40,7 +42,6 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import de.greenrobot.dao.query.LazyList;
@@ -211,8 +212,10 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
spider.addOnSpiderListener(this);
info.state = DownloadInfo.STATE_DOWNLOAD;
info.speed = -1;
info.remaining = -1;
info.total = -1;
info.download = 0;
info.finished = 0;
info.downloaded = 0;
info.legacy = -1;
// Update in DB
EhDB.updateDownloadInfo(info);
@@ -726,22 +729,22 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
}
@Override
public void onPageSuccess(int index, int downloaded, int total) {
public void onPageSuccess(int index, int finished, int downloaded, int total) {
NotifyTask task = mNotifyTaskPool.pop();
if (task == null) {
task = new NotifyTask();
}
task.setOnPageSuccessData(index, downloaded, total);
task.setOnPageSuccessData(index, finished, downloaded, total);
SimpleHandler.getInstance().post(task);
}
@Override
public void onPageFailure(int index, String error, int downloaded, int total) {
public void onPageFailure(int index, String error, int finished, int downloaded, int total) {
NotifyTask task = mNotifyTaskPool.pop();
if (task == null) {
task = new NotifyTask();
}
task.setOnPageFailureDate(index, error, downloaded, total);
task.setOnPageFailureDate(index, error, finished, downloaded, total);
SimpleHandler.getInstance().post(task);
}
@@ -781,6 +784,7 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
private long mReceivedSize;
private int mBytesRead;
private String mError;
private int mFinished;
private int mDownloaded;
private int mTotal;
@@ -802,17 +806,19 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
mBytesRead = bytesRead;
}
public void setOnPageSuccessData(int index, int downloaded, int total) {
public void setOnPageSuccessData(int index, int finished, int downloaded, int total) {
mType = TYPE_ON_PAGE_SUCCESS;
mIndex = index;
mFinished = finished;
mDownloaded = downloaded;
mTotal = total;
}
public void setOnPageFailureDate(int index, String error, int downloaded, int total) {
public void setOnPageFailureDate(int index, String error, int finished, int downloaded, int total) {
mType = TYPE_ON_PAGE_FAILURE;
mIndex = index;
mError = error;
mFinished = finished;
mDownloaded = downloaded;
mTotal = total;
}
@@ -846,15 +852,17 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
break;
}
case TYPE_ON_PAGE_DOWNLOAD: {
mSpeedReminder.up(mBytesRead);
mSpeedReminder.onDownload(mIndex, mContentLength, mReceivedSize, mBytesRead);
break;
}
case TYPE_ON_PAGE_SUCCESS: {
mSpeedReminder.onDone(mIndex);
DownloadInfo info = mCurrentTask;
if (info == null) {
Log.e(TAG, "Current task is null, but it should not be");
} else {
info.download = mDownloaded;
info.finished = mFinished;
info.downloaded = mDownloaded;
info.total = mTotal;
if (mDownloadListener != null) {
mDownloadListener.onGetPage(info);
@@ -867,11 +875,13 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
break;
}
case TYPE_ON_PAGE_FAILURE: {
mSpeedReminder.onDone(mIndex);
DownloadInfo info = mCurrentTask;
if (info == null) {
Log.e(TAG, "Current task is null, but it should not be");
} else {
info.download = mDownloaded;
info.finished = mFinished;
info.downloaded = mDownloaded;
info.total = mTotal;
List<DownloadInfo> list = getInfoListForLabel(info.label);
if (list != null && mDownloadInfoListener != null) {
@@ -881,6 +891,7 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
break;
}
case TYPE_ON_FINISH: {
mSpeedReminder.onFinish();
// Download done
DownloadInfo info = mCurrentTask;
mCurrentTask = null;
@@ -899,9 +910,10 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
// Stop speed count
mSpeedReminder.stop();
// Update state
info.download = mDownloaded;
info.finished = mFinished;
info.downloaded = mDownloaded;
info.total = mTotal;
info.legacy = mTotal - mDownloaded;
info.legacy = mTotal - mFinished;
if (info.legacy == 0) {
info.state = DownloadInfo.STATE_FINISH;
} else {
@@ -932,7 +944,11 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
private boolean mStop = true;
private final AtomicLong mBytesRead = new AtomicLong();
private long mBytesRead;
private long oldSpeed = -1;
private final SparseIJArray mContentLengthMap = new SparseIJArray();
private final SparseIJArray mReceivedSizeMap = new SparseIJArray();
public void start() {
if (mStop) {
@@ -944,20 +960,62 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
public void stop() {
if (!mStop) {
mStop = true;
mBytesRead.lazySet(0L);
mBytesRead = 0;
oldSpeed = -1;
mContentLengthMap.clear();
mReceivedSizeMap.clear();
SimpleHandler.getInstance().removeCallbacks(this);
}
}
public void up(int bytesRead) {
mBytesRead.addAndGet(bytesRead);
public void onDownload(int index, long contentLength, long receivedSize, int bytesRead) {
mContentLengthMap.put(index, contentLength);
mReceivedSizeMap.put(index, receivedSize);
mBytesRead += bytesRead;
}
public void onDone(int index) {
mContentLengthMap.delete(index);
mReceivedSizeMap.delete(index);
}
public void onFinish() {
mContentLengthMap.clear();
mReceivedSizeMap.clear();
}
@Override
public void run() {
DownloadInfo info = mCurrentTask;
if (info != null) {
info.speed = mBytesRead.getAndSet(0) / 2;
long newSpeed = mBytesRead / 2;
if (oldSpeed != -1) {
newSpeed = (long) MathUtils.lerp(oldSpeed, newSpeed, 0.75f);
}
oldSpeed = newSpeed;
info.speed = newSpeed;
// Calculate remaining
if (info.total <= 0) {
info.remaining = -1;
} else if (newSpeed == 0) {
info.remaining = 300L * 24L * 60L * 60L * 1000L; // 300 days
} else {
int downloadingCount = 0;
long downloadingContentLengthSum = 0;
long totalSize = 0;
for (int i = 0, n = Math.max(mContentLengthMap.size(), mReceivedSizeMap.size()); i < n; i++) {
long contentLength = mContentLengthMap.valueAt(i);
long receivedSize = mReceivedSizeMap.valueAt(i);
downloadingCount++;
downloadingContentLengthSum += contentLength;
totalSize += contentLength - receivedSize;
}
if (downloadingCount != 0) {
totalSize += downloadingContentLengthSum * (info.total - info.downloaded - downloadingCount) / downloadingCount;
info.remaining = totalSize / newSpeed * 1000;
}
}
if (mDownloadListener != null) {
mDownloadListener.onDownload(info);
}
@@ -967,6 +1025,8 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
}
}
mBytesRead = 0;
if (!mStop) {
SimpleHandler.getInstance().postDelayed(this, 2000);
}
@@ -34,6 +34,7 @@ import android.util.SparseBooleanArray;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.util.ReadableTime;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IntList;
import com.hippo.yorozuya.SimpleHandler;
@@ -306,10 +307,16 @@ public class DownloadService extends Service implements DownloadManager.Download
speed = 0;
}
String text = FileUtils.humanReadableByteCount(speed, false) + "/S";
long remaining = info.remaining;
if (remaining >= 0) {
text = getString(R.string.download_speed_text_2, text, ReadableTime.getShortTimeInterval(remaining));
} else {
text = getString(R.string.download_speed_text, text);
}
mDownloadingBuilder.setContentTitle(info.galleryInfo.title)
.setContentText(text)
.setContentInfo(info.total == -1 || info.download == -1 ? null : info.download + "/" + info.total)
.setProgress(info.total, info.download, false);
.setContentInfo(info.total == -1 || info.finished == -1 ? null : info.finished + "/" + info.total)
.setProgress(info.total, info.finished, false);
mDownloadingDelay.startForeground();
}
@@ -133,12 +133,12 @@ public class EhGalleryProvider extends GalleryProvider implements SpiderQueen.On
}
@Override
public void onPageSuccess(int index, int downloaded, int total) {
public void onPageSuccess(int index, int finished, int downloaded, int total) {
notifyDataChanged(index);
}
@Override
public void onPageFailure(int index, String error, int downloaded, int total) {
public void onPageFailure(int index, String error, int finished, int downloaded, int total) {
notifyPageFailed(index, error);
}
@@ -212,7 +212,7 @@ public class SpiderQueen implements Runnable {
}
synchronized (mSpiderListeners) {
for (OnSpiderListener listener : mSpiderListeners) {
listener.onPageSuccess(index, mFinishedPages.get(), size);
listener.onPageSuccess(index, mFinishedPages.get(), mDownloadedPages.get(), size);
}
}
}
@@ -225,7 +225,7 @@ public class SpiderQueen implements Runnable {
}
synchronized (mSpiderListeners) {
for (OnSpiderListener listener : mSpiderListeners) {
listener.onPageFailure(index, error, mFinishedPages.get(), size);
listener.onPageFailure(index, error, mFinishedPages.get(), mDownloadedPages.get(), size);
}
}
}
@@ -1210,9 +1210,9 @@ public class SpiderQueen implements Runnable {
*/
void onPageDownload(int index, long contentLength, long receivedSize, int bytesRead);
void onPageSuccess(int index, int downloaded, int total);
void onPageSuccess(int index, int finished, int downloaded, int total);
void onPageFailure(int index, String error, int downloaded, int total);
void onPageFailure(int index, String error, int finished, int downloaded, int total);
/**
* All workers end
@@ -640,14 +640,14 @@ public class DownloadScene extends ToolbarScene
holder.percent.setVisibility(View.VISIBLE);
holder.speed.setVisibility(View.VISIBLE);
if (info.total <= 0 || info.download < 0) {
if (info.total <= 0 || info.finished < 0) {
holder.percent.setText(null);
holder.progressBar.setIndeterminate(true);
} else {
holder.percent.setText(info.download + "/" + info.total);
holder.percent.setText(info.finished + "/" + info.total);
holder.progressBar.setIndeterminate(false);
holder.progressBar.setMax(info.total);
holder.progressBar.setProgress(info.download);
holder.progressBar.setProgress(info.finished);
}
long speed = info.speed;
if (speed < 0) {
@@ -170,6 +170,24 @@ public final class ReadableTime {
return sb.toString();
}
public static String getShortTimeInterval(long time) {
StringBuilder sb = new StringBuilder();
Resources resources = sResources;
for (int i = 0; i < SIZE; i++) {
long multiple = MULTIPLES[i];
long quotient = time / multiple;
if (time > multiple * 1.5 || i == SIZE - 1) {
sb.append(quotient)
.append(" ")
.append(resources.getQuantityString(UNITS[i], (int) quotient));
break;
}
}
return sb.toString();
}
public static String getFilenamableTime(long time) {
synchronized (sDateFormatLock2) {
return FILENAMABLE_DATE_FORMAT.format(new Date(time));