Add DownloadService start range, stop range and delete range

This commit is contained in:
seven332 committed 2016-02-27 22:34:37 +08:00
1 parent 11d492c8fa
commit f47c09deda
7 files changed
+304 -30

No files matched your search

@@ -29,6 +29,7 @@ import com.hippo.ehviewer.dao.DownloadLabelRaw;
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.SimpleHandler;
import java.util.HashMap;
@@ -63,7 +64,9 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
@NonNull
private final SpeedReminder mSpeedReminder;
@Nullable
private DownloadListener mDownloadListener;
@Nullable
private DownloadInfoListener mDownloadInfoListener;
@Nullable
@@ -71,6 +74,7 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
@Nullable
private SpiderQueen mCurrentSpider;
@NonNull
private final ConcurrentPool<NotifyTask> mNotifyTaskPool = new ConcurrentPool<>(5);
public DownloadManager(Context context) {
@@ -181,11 +185,11 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
return mMap.get(label);
}
public void setDownloadInfoListener(DownloadInfoListener downloadInfoListener) {
public void setDownloadInfoListener(@Nullable DownloadInfoListener downloadInfoListener) {
mDownloadInfoListener = downloadInfoListener;
}
public void setDownloadListener(DownloadListener listener) {
public void setDownloadListener(@Nullable DownloadListener listener) {
mDownloadListener = listener;
}
@@ -281,6 +285,38 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
}
}
void startRangeDownload(IntList gidList) {
boolean update = false;
for (int i = 0, n = gidList.size(); i < n; i++) {
int gid = gidList.get(i);
DownloadInfo info = mAllInfoMap.get(gid);
if (null == info) {
Log.d(TAG, "Can't get download info with gid: " + gid);
continue;
}
if (info.state != DownloadInfo.STATE_WAIT) {
update = true;
// Set state DownloadInfo.STATE_WAIT
info.state = DownloadInfo.STATE_WAIT;
// Add to wait list
mWaitList.add(info);
// Update in DB
EhDB.updateDownloadInfo(info);
}
}
if (update) {
// Notify Listener
if (mDownloadInfoListener != null) {
mDownloadInfoListener.onUpdateAll();
}
// Ensure download
ensureDownload();
}
}
void startAllDownload() {
boolean update = false;
// Start all STATE_NONE and STATE_FAILED item
@@ -335,6 +371,18 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
}
}
void stopRangeDownload(IntList gidList) {
stopRangeDownloadInternal(gidList);
// Update listener
if (mDownloadInfoListener != null) {
mDownloadInfoListener.onUpdateAll();
}
// Ensure download
ensureDownload();
}
void stopAllDownload() {
// Stop all in wait list
for (DownloadInfo info : mWaitList) {
@@ -381,6 +429,36 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
}
}
void deleteRangeDownload(IntList gidList) {
stopRangeDownloadInternal(gidList);
for (int i = 0, n = gidList.size(); i < n; i++) {
int gid = gidList.get(i);
DownloadInfo info = mAllInfoMap.get(gid);
if (null == info) {
Log.d(TAG, "Can't get download info with gid: " + gid);
continue;
}
// Remove from DB
EhDB.removeDownloadInfo(info.galleryInfo.gid);
// Remove from all info map
mAllInfoMap.remove(info.galleryInfo.gid);
// Remove from label list
LinkedList<DownloadInfo> list = getInfoListForLabel(info.label);
if (list != null) {
list.remove(info);
}
}
// Update listener
if (mDownloadInfoListener != null) {
mDownloadInfoListener.onReload();
}
}
// Update in DB
// Update listener
// No ensureDownload
@@ -435,6 +513,36 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
return info;
}
// Update in DB
// Update mDownloadListener
private void stopRangeDownloadInternal(IntList gidList) {
// Two way
if (gidList.size() < mWaitList.size()) {
for (int i = 0, n = gidList.size(); i < n; i++) {
DownloadInfo info = stopDownloadInternal(gidList.get(i));
}
} else {
// Check current task
if (mCurrentTask != null && gidList.contains(mCurrentTask.galleryInfo.gid)) {
// Stop current
stopCurrentDownloadInternal();
}
// Check all in wait list
for (Iterator<DownloadInfo> iterator = mWaitList.iterator(); iterator.hasNext();) {
DownloadInfo info = iterator.next();
if (gidList.contains(info.galleryInfo.gid)) {
// Remove from wait list
iterator.remove();
// Update state
info.state = DownloadInfo.STATE_NONE;
// Update in DB
EhDB.updateDownloadInfo(info);
}
}
}
}
boolean isIdle() {
return mCurrentTask == null && mWaitList.isEmpty();
}
@@ -725,6 +833,8 @@ public class DownloadManager implements SpiderQueen.OnSpiderListener {
void onUpdateAll();
void onReload();
void onRemove(DownloadInfo info, List<DownloadInfo> list, int position);
}
@@ -33,21 +33,27 @@ import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IntList;
// TODO Avoid frequent notification
public class DownloadService extends Service implements DownloadManager.DownloadListener {
public static final String ACTION_START = "start";
public static final String ACTION_START_RANGE = "start_range";
public static final String ACTION_START_ALL = "start_all";
public static final String ACTION_STOP = "stop";
public static final String ACTION_STOP_RANGE = "stop_range";
public static final String ACTION_STOP_CURRENT = "stop_current";
public static final String ACTION_STOP_ALL = "stop_all";
public static final String ACTION_DELETE = "delete";
public static final String ACTION_DELETE_RANGE = "delete_range";
public static final String ACTION_CLEAR = "clear";
public static final String KEY_GALLERY_INFO = "gallery_info";
public static final String KEY_LABEL = "label";
public static final String KEY_GID = "gid";
public static final String KEY_GID_LIST = "gid_list";
private static final int ID_DOWNLOADING = 1;
private static final int ID_DOWNLOADED = 2;
@@ -137,6 +143,11 @@ public class DownloadService extends Service implements DownloadManager.Download
if (gi != null && mDownloadManager != null) {
mDownloadManager.startDownload(gi, label);
}
} else if (ACTION_START_RANGE.equals(action)) {
IntList gidList = intent.getParcelableExtra(KEY_GID_LIST);
if (gidList != null && mDownloadManager != null) {
mDownloadManager.startRangeDownload(gidList);
}
} else if (ACTION_START_ALL.equals(action)) {
if (mDownloadManager != null) {
mDownloadManager.startAllDownload();
@@ -150,6 +161,11 @@ public class DownloadService extends Service implements DownloadManager.Download
if (mDownloadManager != null) {
mDownloadManager.stopCurrentDownload();
}
} else if (ACTION_STOP_RANGE.equals(action)) {
IntList gidList = intent.getParcelableExtra(KEY_GID_LIST);
if (gidList != null && mDownloadManager != null) {
mDownloadManager.stopRangeDownload(gidList);
}
} else if (ACTION_STOP_ALL.equals(action)) {
if (mDownloadManager != null) {
mDownloadManager.stopAllDownload();
@@ -159,6 +175,11 @@ public class DownloadService extends Service implements DownloadManager.Download
if (gid != -1 && mDownloadManager != null) {
mDownloadManager.deleteDownload(gid);
}
} else if (ACTION_DELETE_RANGE.equals(action)) {
IntList gidList = intent.getParcelableExtra(KEY_GID_LIST);
if (gidList != null && mDownloadManager != null) {
mDownloadManager.deleteRangeDownload(gidList);
}
} else if (ACTION_CLEAR.equals(action)) {
EhApplication.clearDownloadService(getApplicationContext(), this);
}
@@ -33,6 +33,7 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.transition.TransitionInflater;
import android.util.SparseBooleanArray;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -72,9 +73,11 @@ import com.hippo.widget.FabLayout;
import com.hippo.widget.LoadImageView;
import com.hippo.widget.SimpleImageView;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IntList;
import com.hippo.yorozuya.ObjectUtils;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class DownloadScene extends ToolbarScene
@@ -100,6 +103,9 @@ public class DownloadScene extends ToolbarScene
@Nullable
private List<DownloadInfo> mList;
private final IntList mTempIntList = new IntList();
private final List<GalleryInfo> mTempGalleryInfoList = new LinkedList<>();
// TODO Only single instance
@Override
public int getLaunchMode() {
@@ -386,24 +392,71 @@ public class DownloadScene extends ToolbarScene
@Override
public void onClickSecondaryFab(FabLayout view, FloatingActionButton fab, int position) {
switch (position) {
case 0: // Check all
if (mRecyclerView != null) {
mRecyclerView.checkAll();
EasyRecyclerView recyclerView = mRecyclerView;
if (recyclerView == null) {
return;
}
if (0 == position) {
recyclerView.checkAll();
} else {
List<DownloadInfo> list = mList;
if (list == null) {
return;
}
boolean collectGalleryInfo = position == 3; // Delete
SparseBooleanArray stateArray = recyclerView.getCheckedItemPositions();
for (int i = 0, n = stateArray.size(); i < n; i++) {
if (stateArray.valueAt(i)) {
GalleryInfo gi = list.get(stateArray.keyAt(i)).galleryInfo;
if (collectGalleryInfo) {
mTempGalleryInfoList.add(gi);
}
mTempIntList.add(gi.gid);
}
break;
case 1: // Start
// TODO
break;
case 2: // Stop
// TODO
break;
case 3: // Delete
// TODO
break;
case 4: // Move
// TODO
break;
}
switch (position) {
case 1: { // Start
Intent intent = new Intent(getActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_START_RANGE);
intent.putExtra(DownloadService.KEY_GID_LIST, mTempIntList);
getActivity().startService(intent);
// Clear
mTempIntList.clear();
// Cancel check mode
recyclerView.outOfCustomChoiceMode();
break;
}
case 2: { // Stop
Intent intent = new Intent(getActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_STOP_RANGE);
intent.putExtra(DownloadService.KEY_GID_LIST, mTempIntList);
getActivity().startService(intent);
// Clear
mTempIntList.clear();
// Cancel check mode
recyclerView.outOfCustomChoiceMode();
break;
}
case 3: // Delete
CheckBoxDialogBuilder builder = new CheckBoxDialogBuilder(getContext(),
getString(R.string.download_remove_dialog_message_2, mTempIntList.size()),
getString(R.string.download_remove_dialog_check_text),
Settings.getRemoveImageFiles());
DeleteRangeDialogHelper helper = new DeleteRangeDialogHelper(
mTempGalleryInfoList, mTempIntList, builder);
builder.setTitle(R.string.download_remove_dialog_title)
.setPositiveButton(android.R.string.ok, helper)
.setOnDismissListener(helper)
.show();
break;
case 4: // Move
// TODO
break;
}
}
}
@@ -463,6 +516,21 @@ public class DownloadScene extends ToolbarScene
}
}
@Override
public void onReload() {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
if (mViewTransition != null) {
if (mList != null && mList.size() == 0) {
mViewTransition.showView(1);
} else {
mViewTransition.showView(0);
}
}
}
@Override
public void onRemove(DownloadInfo info, List<DownloadInfo> list, int position) {
if (mList != list) {
@@ -541,6 +609,18 @@ public class DownloadScene extends ToolbarScene
holder.speed.setText(FileUtils.humanReadableByteCount(speed, false) + "/S");
}
private static void deleteFileAsync(UniFile... files) {
new AsyncTask<UniFile, Void, Void>() {
@Override
protected Void doInBackground(UniFile... params) {
for (UniFile file: params) {
file.delete();
}
return null;
}
}.execute(files);
}
private class DeleteDialogHelper implements DialogInterface.OnClickListener {
private final GalleryInfo mGalleryInfo;
@@ -563,6 +643,7 @@ public class DownloadScene extends ToolbarScene
intent.putExtra(DownloadService.KEY_GID, mGalleryInfo.gid);
getActivity().startService(intent);
// Delete image files
boolean checked = mBuilder.isChecked();
Settings.putRemoveImageFiles(checked);
if (checked) {
@@ -570,19 +651,67 @@ public class DownloadScene extends ToolbarScene
EhDB.removeDownloadDirname(mGalleryInfo.gid);
// Delete file
UniFile file = SpiderDen.getGalleryDownloadDir(mGalleryInfo);
new AsyncTask<UniFile, Void, Void>() {
@Override
protected Void doInBackground(UniFile... params) {
for (UniFile file: params) {
file.delete();
}
return null;
}
}.execute(file);
deleteFileAsync(file);
}
}
}
private class DeleteRangeDialogHelper implements DialogInterface.OnClickListener,
DialogInterface.OnDismissListener {
private final List<GalleryInfo> mGalleryInfoList;
private final IntList mGidList;
private final CheckBoxDialogBuilder mBuilder;
public DeleteRangeDialogHelper(List<GalleryInfo> galleryInfoList,
IntList gidList, CheckBoxDialogBuilder builder) {
mGalleryInfoList = galleryInfoList;
mGidList = gidList;
mBuilder = builder;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which != DialogInterface.BUTTON_POSITIVE) {
return;
}
// Delete
Intent intent = new Intent(getActivity(), DownloadService.class);
intent.setAction(DownloadService.ACTION_DELETE_RANGE);
intent.putExtra(DownloadService.KEY_GID_LIST, mGidList);
getActivity().startService(intent);
// Delete image files
boolean checked = mBuilder.isChecked();
Settings.putRemoveImageFiles(checked);
if (checked) {
UniFile[] files = new UniFile[mGalleryInfoList.size()];
int i = 0;
for (GalleryInfo gi: mGalleryInfoList) {
// Remove download path
EhDB.removeDownloadDirname(gi.gid);
// Put file
files[i] = SpiderDen.getGalleryDownloadDir(gi);
i++;
}
// Delete file
deleteFileAsync(files);
}
// Cancel check mode
if (mRecyclerView != null) {
mRecyclerView.outOfCustomChoiceMode();
}
}
@Override
public void onDismiss(DialogInterface dialog) {
mGalleryInfoList.clear();
mGidList.clear();
}
}
private class DownloadHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final LoadImageView thumb;