import android.os.Message;
import android.os.Process;
import android.support.v4.app.NotificationCompat;
+import android.util.Pair;
public class FileDownloader extends Service implements OnDatatransferProgressListener {
public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
public static final String EXTRA_FILE_PATH = "FILE_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";
private static final String TAG = "FileDownloader";
public static String getDownloadAddedMessage() {
- return FileDownloader.class.getName().toString() + DOWNLOAD_ADDED_MESSAGE;
+ return FileDownloader.class.getName() + DOWNLOAD_ADDED_MESSAGE;
}
public static String getDownloadFinishMessage() {
- return FileDownloader.class.getName().toString() + DOWNLOAD_FINISH_MESSAGE;
+ return FileDownloader.class.getName() + DOWNLOAD_FINISH_MESSAGE;
}
/**
final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
+ /*
if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
new Thread(new Runnable() {
}).start();
} else {
+ */
AbstractList<String> requestedDownloads = new Vector<String>();
try {
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((FileDownloaderBinder) mBinder);
requestedDownloads.add(downloadKey);
storageManager.saveFile(file);
*/
- sendBroadcastNewDownload(newDownload);
+ sendBroadcastNewDownload(newDownload, putResult.second);
} catch (IllegalArgumentException e) {
Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
msg.obj = requestedDownloads;
mServiceHandler.sendMessage(msg);
}
- }
+ //}
}
return START_NOT_STICKY;
* @param file A file in the queue of pending downloads
*/
public void cancel(Account account, OCFile file) {
- DownloadFileOperation download = null;
- download = mPendingDownloads.remove(account, file.getRemotePath());
+ Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.remove(account, file.getRemotePath());
+ DownloadFileOperation download = removeResult.first;
if (download != null) {
download.cancel();
} else {
// TODO synchronize
if (mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
- account.name.equals(mLastAccount)) {
+ account.name.equals(mLastAccount.name)) {
mCurrentDownload.cancel();
}
}
downloadResult = new RemoteOperationResult(e);
} 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);
}
}
/**
* Sends a broadcast when a download finishes in order to the interested activities can update their view
*
- * @param download Finished download operation
- * @param downloadResult Result of the download operation
+ * @param download Finished 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());
end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess());
end.putExtra(ACCOUNT_NAME, download.getAccount().name);
end.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
end.putExtra(EXTRA_FILE_PATH, download.getSavePath());
+ if (unlinkedFromRemotePath != null) {
+ end.putExtra(EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath);
+ }
sendStickyBroadcast(end);
}
/**
* 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());
added.putExtra(ACCOUNT_NAME, download.getAccount().name);
added.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
added.putExtra(EXTRA_FILE_PATH, download.getSavePath());
+ added.putExtra(EXTRA_LINKED_TO_PATH, linkedToRemotePath);
sendStickyBroadcast(added);
}
* Cancel operation
* @param account ownCloud account where the remote file is stored.
* @param file File OCFile
- */
+ *-/
public void cancel(Account account, OCFile file){
DownloadFileOperation download = null;
//String targetKey = buildKey(account, file.getRemotePath());
}
}
- */
+ *-/
} else {
// this is not really expected...
}
}
}
+ */
}
package com.owncloud.android.files.services;
import android.accounts.Account;
+import android.util.Pair;
import com.owncloud.android.datamodel.OCFile;
}
- 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);
Node<V> valuedNode = new Node(targetKey, value);
mMap.putIfAbsent(
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);
Node<V> firstRemoved = mMap.remove(targetKey);
+ String unlinkedFrom = null;
if (firstRemoved != null) {
/// remove children
/// remove ancestors if only here due to firstRemoved
Node<V> removed = firstRemoved;
Node<V> parent = removed.getParent();
+ boolean unlinked = false;
while (parent != null) {
parent.removeChild(removed);
if (!parent.hasChildren()) {
removed = mMap.remove(parent.getKey());
parent = removed.getParent();
} else {
- parent = null;
+ break;
}
}
+
+ if (parent != null) {
+ unlinkedFrom = parent.getKey().substring(account.name.length());
+ }
}
if (firstRemoved != null) {
- return firstRemoved.getPayload();
+ return new Pair<V, String>(firstRemoved.getPayload(), unlinkedFrom);
} else {
- return null;
+ return new Pair<V, String>(null, unlinkedFrom);
}
}
* current folder.
*/
private class DownloadFinishReceiver extends BroadcastReceiver {
+
+ int refreshCounter = 0;
@Override
public void onReceive(Context context, Intent intent) {
try {
boolean sameAccount = isSameAccount(context, intent);
String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
boolean isDescendant = isDescendant(downloadedRemotePath);
-
+
if (sameAccount && isDescendant) {
- refreshListOfFilesFragment();
- refreshSecondFragment(intent.getAction(), downloadedRemotePath, intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
+ String linkedToRemotePath = intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
+ 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) {
- mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); // Update the file to send
+ mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
if (mWaitingToSend.isDown()) {
sendDownloadedFile();
}
private boolean isDescendant(String downloadedRemotePath) {
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) {