mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 21:55:48 +03:00
Minimize refresh of list of files on reception of events from FileDownloader
This commit is contained in:
parent
265e32dee6
commit
a07937cb6f
4 changed files with 84 additions and 33 deletions
|
@ -63,6 +63,7 @@ import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
public class FileDownloader extends Service implements OnDatatransferProgressListener {
|
public class FileDownloader extends Service implements OnDatatransferProgressListener {
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
|
public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
|
||||||
public static final String EXTRA_FILE_PATH = "FILE_PATH";
|
public static final String EXTRA_FILE_PATH = "FILE_PATH";
|
||||||
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
|
public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
|
||||||
|
public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
|
||||||
public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
|
public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
|
||||||
|
|
||||||
private static final String TAG = "FileDownloader";
|
private static final String TAG = "FileDownloader";
|
||||||
|
@ -97,11 +99,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
|
|
||||||
|
|
||||||
public static String getDownloadAddedMessage() {
|
public static String getDownloadAddedMessage() {
|
||||||
return FileDownloader.class.getName().toString() + DOWNLOAD_ADDED_MESSAGE;
|
return FileDownloader.class.getName() + DOWNLOAD_ADDED_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDownloadFinishMessage() {
|
public static String getDownloadFinishMessage() {
|
||||||
return FileDownloader.class.getName().toString() + DOWNLOAD_FINISH_MESSAGE;
|
return FileDownloader.class.getName() + DOWNLOAD_FINISH_MESSAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,6 +138,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
|
final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
|
||||||
final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
|
final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
|
||||||
|
|
||||||
|
/*
|
||||||
if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
|
if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
|
||||||
|
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
|
@ -146,11 +149,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
*/
|
||||||
|
|
||||||
AbstractList<String> requestedDownloads = new Vector<String>();
|
AbstractList<String> requestedDownloads = new Vector<String>();
|
||||||
try {
|
try {
|
||||||
DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
|
DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
|
||||||
String downloadKey = mPendingDownloads.putIfAbsent(account, file.getRemotePath(), newDownload);
|
Pair<String, String> putResult = mPendingDownloads.putIfAbsent(
|
||||||
|
account, file.getRemotePath(), newDownload
|
||||||
|
);
|
||||||
|
String downloadKey = putResult.first;
|
||||||
newDownload.addDatatransferProgressListener(this);
|
newDownload.addDatatransferProgressListener(this);
|
||||||
newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
|
newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
|
||||||
requestedDownloads.add(downloadKey);
|
requestedDownloads.add(downloadKey);
|
||||||
|
@ -163,7 +170,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
storageManager.saveFile(file);
|
storageManager.saveFile(file);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sendBroadcastNewDownload(newDownload);
|
sendBroadcastNewDownload(newDownload, putResult.second);
|
||||||
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
|
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
|
||||||
|
@ -176,7 +183,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
msg.obj = requestedDownloads;
|
msg.obj = requestedDownloads;
|
||||||
mServiceHandler.sendMessage(msg);
|
mServiceHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
return START_NOT_STICKY;
|
return START_NOT_STICKY;
|
||||||
|
@ -227,14 +234,14 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
* @param file A file in the queue of pending downloads
|
* @param file A file in the queue of pending downloads
|
||||||
*/
|
*/
|
||||||
public void cancel(Account account, OCFile file) {
|
public void cancel(Account account, OCFile file) {
|
||||||
DownloadFileOperation download = null;
|
Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.remove(account, file.getRemotePath());
|
||||||
download = mPendingDownloads.remove(account, file.getRemotePath());
|
DownloadFileOperation download = removeResult.first;
|
||||||
if (download != null) {
|
if (download != null) {
|
||||||
download.cancel();
|
download.cancel();
|
||||||
} else {
|
} else {
|
||||||
// TODO synchronize
|
// TODO synchronize
|
||||||
if (mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
|
if (mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
|
||||||
account.name.equals(mLastAccount)) {
|
account.name.equals(mLastAccount.name)) {
|
||||||
mCurrentDownload.cancel();
|
mCurrentDownload.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,14 +388,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
downloadResult = new RemoteOperationResult(e);
|
downloadResult = new RemoteOperationResult(e);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
mPendingDownloads.remove(mLastAccount, mCurrentDownload.getRemotePath());
|
Pair<DownloadFileOperation, String> removeResult =
|
||||||
|
mPendingDownloads.remove(mLastAccount, mCurrentDownload.getRemotePath());
|
||||||
|
|
||||||
|
/// notify result
|
||||||
|
notifyDownloadResult(mCurrentDownload, downloadResult);
|
||||||
|
|
||||||
|
sendBroadcastDownloadFinished(mCurrentDownload, downloadResult, removeResult.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// notify result
|
|
||||||
notifyDownloadResult(mCurrentDownload, downloadResult);
|
|
||||||
|
|
||||||
sendBroadcastDownloadFinished(mCurrentDownload, downloadResult);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,15 +562,22 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
/**
|
/**
|
||||||
* Sends a broadcast when a download finishes in order to the interested activities can update their view
|
* Sends a broadcast when a download finishes in order to the interested activities can update their view
|
||||||
*
|
*
|
||||||
* @param download Finished download operation
|
* @param download Finished download operation
|
||||||
* @param downloadResult Result of the download operation
|
* @param downloadResult Result of the download operation
|
||||||
|
* @param unlinkedFromRemotePath Path in the downloads tree where the download was unlinked from
|
||||||
*/
|
*/
|
||||||
private void sendBroadcastDownloadFinished(DownloadFileOperation download, RemoteOperationResult downloadResult) {
|
private void sendBroadcastDownloadFinished(
|
||||||
|
DownloadFileOperation download,
|
||||||
|
RemoteOperationResult downloadResult,
|
||||||
|
String unlinkedFromRemotePath) {
|
||||||
Intent end = new Intent(getDownloadFinishMessage());
|
Intent end = new Intent(getDownloadFinishMessage());
|
||||||
end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess());
|
end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess());
|
||||||
end.putExtra(ACCOUNT_NAME, download.getAccount().name);
|
end.putExtra(ACCOUNT_NAME, download.getAccount().name);
|
||||||
end.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
|
end.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
|
||||||
end.putExtra(EXTRA_FILE_PATH, download.getSavePath());
|
end.putExtra(EXTRA_FILE_PATH, download.getSavePath());
|
||||||
|
if (unlinkedFromRemotePath != null) {
|
||||||
|
end.putExtra(EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath);
|
||||||
|
}
|
||||||
sendStickyBroadcast(end);
|
sendStickyBroadcast(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,13 +585,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
/**
|
/**
|
||||||
* Sends a broadcast when a new download is added to the queue.
|
* Sends a broadcast when a new download is added to the queue.
|
||||||
*
|
*
|
||||||
* @param download Added download operation
|
* @param download Added download operation
|
||||||
|
* @param linkedToRemotePath Path in the downloads tree where the download was linked to
|
||||||
*/
|
*/
|
||||||
private void sendBroadcastNewDownload(DownloadFileOperation download) {
|
private void sendBroadcastNewDownload(DownloadFileOperation download, String linkedToRemotePath) {
|
||||||
Intent added = new Intent(getDownloadAddedMessage());
|
Intent added = new Intent(getDownloadAddedMessage());
|
||||||
added.putExtra(ACCOUNT_NAME, download.getAccount().name);
|
added.putExtra(ACCOUNT_NAME, download.getAccount().name);
|
||||||
added.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
|
added.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
|
||||||
added.putExtra(EXTRA_FILE_PATH, download.getSavePath());
|
added.putExtra(EXTRA_FILE_PATH, download.getSavePath());
|
||||||
|
added.putExtra(EXTRA_LINKED_TO_PATH, linkedToRemotePath);
|
||||||
sendStickyBroadcast(added);
|
sendStickyBroadcast(added);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +601,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
* Cancel operation
|
* Cancel operation
|
||||||
* @param account ownCloud account where the remote file is stored.
|
* @param account ownCloud account where the remote file is stored.
|
||||||
* @param file File OCFile
|
* @param file File OCFile
|
||||||
*/
|
*-/
|
||||||
public void cancel(Account account, OCFile file){
|
public void cancel(Account account, OCFile file){
|
||||||
DownloadFileOperation download = null;
|
DownloadFileOperation download = null;
|
||||||
//String targetKey = buildKey(account, file.getRemotePath());
|
//String targetKey = buildKey(account, file.getRemotePath());
|
||||||
|
@ -613,7 +630,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
*-/
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// this is not really expected...
|
// this is not really expected...
|
||||||
|
@ -624,5 +641,6 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package com.owncloud.android.files.services;
|
package com.owncloud.android.files.services;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import com.owncloud.android.datamodel.OCFile;
|
import com.owncloud.android.datamodel.OCFile;
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ public class IndexedForest<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public /* synchronized */ String putIfAbsent(Account account, String remotePath, V value) {
|
public /* synchronized */ Pair<String, String> putIfAbsent(Account account, String remotePath, V value) {
|
||||||
String targetKey = buildKey(account, remotePath);
|
String targetKey = buildKey(account, remotePath);
|
||||||
Node<V> valuedNode = new Node(targetKey, value);
|
Node<V> valuedNode = new Node(targetKey, value);
|
||||||
mMap.putIfAbsent(
|
mMap.putIfAbsent(
|
||||||
|
@ -121,12 +122,17 @@ public class IndexedForest<V> {
|
||||||
currentNode = parentNode;
|
currentNode = parentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetKey;
|
String linkedTo = OCFile.ROOT_PATH;
|
||||||
|
if (linked) {
|
||||||
|
linkedTo = parentNode.getKey().substring(account.name.length());
|
||||||
|
}
|
||||||
|
return new Pair<String, String>(targetKey, linkedTo);
|
||||||
};
|
};
|
||||||
|
|
||||||
public /* synchronized */ V remove(Account account, String remotePath) {
|
public /* synchronized */ Pair<V, String> remove(Account account, String remotePath) {
|
||||||
String targetKey = buildKey(account, remotePath);
|
String targetKey = buildKey(account, remotePath);
|
||||||
Node<V> firstRemoved = mMap.remove(targetKey);
|
Node<V> firstRemoved = mMap.remove(targetKey);
|
||||||
|
String unlinkedFrom = null;
|
||||||
|
|
||||||
if (firstRemoved != null) {
|
if (firstRemoved != null) {
|
||||||
/// remove children
|
/// remove children
|
||||||
|
@ -135,21 +141,26 @@ public class IndexedForest<V> {
|
||||||
/// remove ancestors if only here due to firstRemoved
|
/// remove ancestors if only here due to firstRemoved
|
||||||
Node<V> removed = firstRemoved;
|
Node<V> removed = firstRemoved;
|
||||||
Node<V> parent = removed.getParent();
|
Node<V> parent = removed.getParent();
|
||||||
|
boolean unlinked = false;
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
parent.removeChild(removed);
|
parent.removeChild(removed);
|
||||||
if (!parent.hasChildren()) {
|
if (!parent.hasChildren()) {
|
||||||
removed = mMap.remove(parent.getKey());
|
removed = mMap.remove(parent.getKey());
|
||||||
parent = removed.getParent();
|
parent = removed.getParent();
|
||||||
} else {
|
} else {
|
||||||
parent = null;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parent != null) {
|
||||||
|
unlinkedFrom = parent.getKey().substring(account.name.length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstRemoved != null) {
|
if (firstRemoved != null) {
|
||||||
return firstRemoved.getPayload();
|
return new Pair<V, String>(firstRemoved.getPayload(), unlinkedFrom);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return new Pair<V, String>(null, unlinkedFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1261,20 +1261,30 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
|
||||||
* current folder.
|
* current folder.
|
||||||
*/
|
*/
|
||||||
private class DownloadFinishReceiver extends BroadcastReceiver {
|
private class DownloadFinishReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
int refreshCounter = 0;
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
try {
|
try {
|
||||||
boolean sameAccount = isSameAccount(context, intent);
|
boolean sameAccount = isSameAccount(context, intent);
|
||||||
String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
|
String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
|
||||||
boolean isDescendant = isDescendant(downloadedRemotePath);
|
boolean isDescendant = isDescendant(downloadedRemotePath);
|
||||||
|
|
||||||
if (sameAccount && isDescendant) {
|
if (sameAccount && isDescendant) {
|
||||||
refreshListOfFilesFragment();
|
String linkedToRemotePath = intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
|
||||||
refreshSecondFragment(intent.getAction(), downloadedRemotePath, intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
|
if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
|
||||||
|
Log_OC.v(TAG, "NOW: refresh #" + ++refreshCounter);
|
||||||
|
refreshListOfFilesFragment();
|
||||||
|
}
|
||||||
|
refreshSecondFragment(
|
||||||
|
intent.getAction(),
|
||||||
|
downloadedRemotePath,
|
||||||
|
intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mWaitingToSend != null) {
|
if (mWaitingToSend != null) {
|
||||||
mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); // Update the file to send
|
mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
|
||||||
if (mWaitingToSend.isDown()) {
|
if (mWaitingToSend.isDown()) {
|
||||||
sendDownloadedFile();
|
sendDownloadedFile();
|
||||||
}
|
}
|
||||||
|
@ -1289,7 +1299,19 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
|
||||||
|
|
||||||
private boolean isDescendant(String downloadedRemotePath) {
|
private boolean isDescendant(String downloadedRemotePath) {
|
||||||
OCFile currentDir = getCurrentDir();
|
OCFile currentDir = getCurrentDir();
|
||||||
return (currentDir != null && downloadedRemotePath != null && downloadedRemotePath.startsWith(currentDir.getRemotePath()));
|
return (
|
||||||
|
currentDir != null &&
|
||||||
|
downloadedRemotePath != null &&
|
||||||
|
downloadedRemotePath.startsWith(currentDir.getRemotePath())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAscendant(String linkedToRemotePath) {
|
||||||
|
OCFile currentDir = getCurrentDir();
|
||||||
|
return (
|
||||||
|
currentDir != null &&
|
||||||
|
currentDir.getRemotePath().startsWith(linkedToRemotePath)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSameAccount(Context context, Intent intent) {
|
private boolean isSameAccount(Context context, Intent intent) {
|
||||||
|
|
|
@ -426,7 +426,7 @@ ViewPager.OnPageChangeListener, OnRemoteOperationListener {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class waiting for broadcast events from the {@link FielDownloader} service.
|
* Class waiting for broadcast events from the {@link FileDownloader} service.
|
||||||
*
|
*
|
||||||
* Updates the UI when a download is started or finished, provided that it is relevant for the
|
* Updates the UI when a download is started or finished, provided that it is relevant for the
|
||||||
* folder displayed in the gallery.
|
* folder displayed in the gallery.
|
||||||
|
|
Loading…
Reference in a new issue