mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 21:55:48 +03:00
Added indexed tree of folders downloading anything
This commit is contained in:
parent
e2a7138e0e
commit
5b54915209
9 changed files with 313 additions and 113 deletions
|
@ -140,7 +140,9 @@ public class FileMenuFilter {
|
|||
boolean downloading = false;
|
||||
boolean uploading = false;
|
||||
if (mComponentsGetter != null && mFile != null && mAccount != null) {
|
||||
downloading = mFile.isDownloading() || mFile.isSynchronizing();
|
||||
//downloading = mFile.isDownloading() || mFile.isSynchronizing();
|
||||
FileDownloaderBinder downloaderBinder = mComponentsGetter.getFileDownloaderBinder();
|
||||
downloading = (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile));
|
||||
FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
|
||||
uploading = (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile));
|
||||
}
|
||||
|
|
|
@ -287,7 +287,8 @@ public class FileOperationsHelper {
|
|||
if (!file.isFolder()) {
|
||||
FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder();
|
||||
FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
|
||||
if (downloaderBinder != null && file.isDownloading()) {
|
||||
//if (downloaderBinder != null && file.isDownloading()) {
|
||||
if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) {
|
||||
// Remove etag for parent, if file is a keep_in_sync
|
||||
if (file.keepInSync()) {
|
||||
OCFile parent = mFileActivity.getStorageManager().getFileById(file.getParentId());
|
||||
|
|
|
@ -26,8 +26,6 @@ import java.util.HashMap;
|
|||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
|
@ -89,7 +87,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
private Account mLastAccount = null;
|
||||
private FileDataStorageManager mStorageManager;
|
||||
|
||||
private ConcurrentMap<String, DownloadFileOperation> mPendingDownloads = new ConcurrentHashMap<String, DownloadFileOperation>();
|
||||
private IndexedForest<DownloadFileOperation> mPendingDownloads = new IndexedForest<DownloadFileOperation>();
|
||||
|
||||
private DownloadFileOperation mCurrentDownload = null;
|
||||
|
||||
private NotificationManager mNotificationManager;
|
||||
|
@ -105,17 +104,6 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
return FileDownloader.class.getName().toString() + DOWNLOAD_FINISH_MESSAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a key for mPendingDownloads from the account and file to download
|
||||
*
|
||||
* @param account Account where the file to download is stored
|
||||
* @param file File to download
|
||||
*/
|
||||
private String buildRemoteName(Account account, OCFile file) {
|
||||
return account.name + file.getRemotePath();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Service initialization
|
||||
*/
|
||||
|
@ -133,16 +121,14 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
|
||||
/**
|
||||
* Entry point to add one or several files to the queue of downloads.
|
||||
*
|
||||
* New downloads are added calling to startService(), resulting in a call to this method. This ensures the service will keep on working
|
||||
* although the caller activity goes away.
|
||||
*
|
||||
* New downloads are added calling to startService(), resulting in a call to this method.
|
||||
* This ensures the service will keep on working although the caller activity goes away.
|
||||
*/
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if ( !intent.hasExtra(EXTRA_ACCOUNT) ||
|
||||
!intent.hasExtra(EXTRA_FILE)
|
||||
/*!intent.hasExtra(EXTRA_FILE_PATH) ||
|
||||
!intent.hasExtra(EXTRA_REMOTE_PATH)*/
|
||||
) {
|
||||
Log_OC.e(TAG, "Not enough information provided in intent");
|
||||
return START_NOT_STICKY;
|
||||
|
@ -161,19 +147,21 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
|
||||
} else {
|
||||
|
||||
AbstractList<String> requestedDownloads = new Vector<String>(); // dvelasco: now this always contains just one element, but that can change in a near future (download of multiple selection)
|
||||
String downloadKey = buildRemoteName(account, file);
|
||||
AbstractList<String> requestedDownloads = new Vector<String>();
|
||||
try {
|
||||
DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
|
||||
mPendingDownloads.putIfAbsent(downloadKey, newDownload);
|
||||
String downloadKey = mPendingDownloads.putIfAbsent(account, file.getRemotePath(), newDownload);
|
||||
newDownload.addDatatransferProgressListener(this);
|
||||
newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
|
||||
requestedDownloads.add(downloadKey);
|
||||
|
||||
// Store file on db with state 'downloading'
|
||||
/*
|
||||
TODO - check if helps with UI responsiveness, letting only folders use FileDownloaderBinder to check
|
||||
FileDataStorageManager storageManager = new FileDataStorageManager(account, getContentResolver());
|
||||
file.setDownloading(true);
|
||||
storageManager.saveFile(file);
|
||||
*/
|
||||
|
||||
sendBroadcastNewDownload(newDownload);
|
||||
|
||||
|
@ -193,11 +181,12 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provides a binder object that clients can use to perform operations on the queue of downloads, excepting the addition of new files.
|
||||
*
|
||||
* Provides a binder object that clients can use to perform operations on the queue of downloads,
|
||||
* excepting the addition of new files.
|
||||
*
|
||||
* Implemented to perform cancellation, pause and resume of existing downloads.
|
||||
*/
|
||||
@Override
|
||||
|
@ -215,18 +204,20 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
return false; // not accepting rebinding (default behaviour)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Binder to let client components to perform operations on the queue of downloads.
|
||||
*
|
||||
*
|
||||
* It provides by itself the available operations.
|
||||
*/
|
||||
public class FileDownloaderBinder extends Binder implements OnDatatransferProgressListener {
|
||||
|
||||
/**
|
||||
* Map of listeners that will be reported about progress of downloads from a {@link FileDownloaderBinder} instance
|
||||
* Map of listeners that will be reported about progress of downloads from a {@link FileDownloaderBinder}
|
||||
* instance.
|
||||
*/
|
||||
private Map<String, OnDatatransferProgressListener> mBoundListeners = new HashMap<String, OnDatatransferProgressListener>();
|
||||
private Map<Long, OnDatatransferProgressListener> mBoundListeners =
|
||||
new HashMap<Long, OnDatatransferProgressListener>();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -237,9 +228,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
*/
|
||||
public void cancel(Account account, OCFile file) {
|
||||
DownloadFileOperation download = null;
|
||||
synchronized (mPendingDownloads) {
|
||||
download = mPendingDownloads.remove(buildRemoteName(account, file));
|
||||
}
|
||||
download = mPendingDownloads.remove(account, file.getRemotePath());
|
||||
if (download != null) {
|
||||
download.cancel();
|
||||
}
|
||||
|
@ -252,32 +241,19 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
|
||||
|
||||
/**
|
||||
* Returns True when the file described by 'file' in the ownCloud account 'account' is downloading or waiting to download.
|
||||
* Returns True when the file described by 'file' in the ownCloud account 'account' is downloading or
|
||||
* waiting to download.
|
||||
*
|
||||
* If 'file' is a directory, returns 'true' if some of its descendant files is downloading or waiting to download.
|
||||
* If 'file' is a directory, returns 'true' if any of its descendant files is downloading or
|
||||
* waiting to download.
|
||||
*
|
||||
* @param account Owncloud account where the remote file is stored.
|
||||
* @param account ownCloud account where the remote file is stored.
|
||||
* @param file A file that could be in the queue of downloads.
|
||||
*/
|
||||
/*
|
||||
public boolean isDownloading(Account account, OCFile file) {
|
||||
if (account == null || file == null) return false;
|
||||
String targetKey = buildRemoteName(account, file);
|
||||
synchronized (mPendingDownloads) {
|
||||
if (file.isFolder()) {
|
||||
// this can be slow if there are many downloads :(
|
||||
Iterator<String> it = mPendingDownloads.keySet().iterator();
|
||||
boolean found = false;
|
||||
while (it.hasNext() && !found) {
|
||||
found = it.next().startsWith(targetKey);
|
||||
}
|
||||
return found;
|
||||
} else {
|
||||
return (mPendingDownloads.containsKey(targetKey));
|
||||
}
|
||||
}
|
||||
return (mPendingDownloads.contains(account, file.getRemotePath()));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
|
@ -285,12 +261,14 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
*
|
||||
* @param listener Object to notify about progress of transfer.
|
||||
* @param account ownCloud account holding the file of interest.
|
||||
* @param file {@link OCfile} of interest for listener.
|
||||
* @param file {@link OCFile} of interest for listener.
|
||||
*/
|
||||
public void addDatatransferProgressListener (OnDatatransferProgressListener listener, Account account, OCFile file) {
|
||||
public void addDatatransferProgressListener (
|
||||
OnDatatransferProgressListener listener, Account account, OCFile file
|
||||
) {
|
||||
if (account == null || file == null || listener == null) return;
|
||||
String targetKey = buildRemoteName(account, file);
|
||||
mBoundListeners.put(targetKey, listener);
|
||||
//String targetKey = buildKey(account, file.getRemotePath());
|
||||
mBoundListeners.put(file.getFileId(), listener);
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,21 +277,24 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
*
|
||||
* @param listener Object to notify about progress of transfer.
|
||||
* @param account ownCloud account holding the file of interest.
|
||||
* @param file {@link OCfile} of interest for listener.
|
||||
* @param file {@link OCFile} of interest for listener.
|
||||
*/
|
||||
public void removeDatatransferProgressListener (OnDatatransferProgressListener listener, Account account, OCFile file) {
|
||||
public void removeDatatransferProgressListener (
|
||||
OnDatatransferProgressListener listener, Account account, OCFile file
|
||||
) {
|
||||
if (account == null || file == null || listener == null) return;
|
||||
String targetKey = buildRemoteName(account, file);
|
||||
if (mBoundListeners.get(targetKey) == listener) {
|
||||
mBoundListeners.remove(targetKey);
|
||||
//String targetKey = buildKey(account, file.getRemotePath());
|
||||
Long fileId = file.getFileId();
|
||||
if (mBoundListeners.get(fileId) == listener) {
|
||||
mBoundListeners.remove(fileId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
|
||||
String fileName) {
|
||||
String key = buildRemoteName(mCurrentDownload.getAccount(), mCurrentDownload.getFile());
|
||||
OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
|
||||
//String key = buildKey(mCurrentDownload.getAccount(), mCurrentDownload.getFile().getRemotePath());
|
||||
OnDatatransferProgressListener boundListener = mBoundListeners.get(mCurrentDownload.getFile().getFileId());
|
||||
if (boundListener != null) {
|
||||
boundListener.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName);
|
||||
}
|
||||
|
@ -358,11 +339,9 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
* @param downloadKey Key to access the download to perform, contained in mPendingDownloads
|
||||
*/
|
||||
private void downloadFile(String downloadKey) {
|
||||
|
||||
synchronized(mPendingDownloads) {
|
||||
mCurrentDownload = mPendingDownloads.get(downloadKey);
|
||||
}
|
||||
|
||||
|
||||
mCurrentDownload = mPendingDownloads.get(downloadKey);
|
||||
|
||||
if (mCurrentDownload != null) {
|
||||
|
||||
notifyDownloadStart(mCurrentDownload);
|
||||
|
@ -383,21 +362,20 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
downloadResult = mCurrentDownload.execute(mDownloadClient);
|
||||
if (downloadResult.isSuccess()) {
|
||||
saveDownloadedFile();
|
||||
} else {
|
||||
/*} else {
|
||||
updateUnsuccessfulDownloadedFile();
|
||||
*/
|
||||
}
|
||||
|
||||
} catch (AccountsException e) {
|
||||
Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
|
||||
Log_OC.e(TAG, "Error while trying to get authorization for " + mLastAccount.name, e);
|
||||
downloadResult = new RemoteOperationResult(e);
|
||||
} catch (IOException e) {
|
||||
Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
|
||||
Log_OC.e(TAG, "Error while trying to get authorization for " + mLastAccount.name, e);
|
||||
downloadResult = new RemoteOperationResult(e);
|
||||
|
||||
} finally {
|
||||
synchronized(mPendingDownloads) {
|
||||
mPendingDownloads.remove(downloadKey);
|
||||
}
|
||||
mPendingDownloads.remove(mLastAccount, mCurrentDownload.getRemotePath());
|
||||
}
|
||||
|
||||
|
||||
|
@ -425,7 +403,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
file.setStoragePath(mCurrentDownload.getSavePath());
|
||||
file.setFileLength((new File(mCurrentDownload.getSavePath()).length()));
|
||||
file.setRemoteId(mCurrentDownload.getFile().getRemoteId());
|
||||
file.setDownloading(false);
|
||||
//file.setDownloading(false);
|
||||
mStorageManager.saveFile(file);
|
||||
mStorageManager.triggerMediaScan(file.getStoragePath());
|
||||
}
|
||||
|
@ -484,7 +462,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
* Callback method to update the progress bar in the status notification.
|
||||
*/
|
||||
@Override
|
||||
public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath) {
|
||||
public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath)
|
||||
{
|
||||
int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer));
|
||||
if (percent != mLastPercent) {
|
||||
mNotificationBuilder.setProgress(100, percent, totalToTransfer < 0);
|
||||
|
@ -528,7 +507,9 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
// let the user update credentials with one click
|
||||
Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
|
||||
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, download.getAccount());
|
||||
updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
|
||||
updateAccountCredentials.putExtra(
|
||||
AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
|
||||
);
|
||||
updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
|
||||
|
@ -536,7 +517,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
.setContentIntent(PendingIntent.getActivity(
|
||||
this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT));
|
||||
|
||||
mDownloadClient = null; // grant that future retries on the same account will get the fresh credentials
|
||||
mDownloadClient = null; // grant that future retries on the same account will get the fresh credentials
|
||||
|
||||
} else {
|
||||
// TODO put something smart in showDetailsIntent
|
||||
|
@ -546,7 +527,9 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
this, (int) System.currentTimeMillis(), showDetailsIntent, 0));
|
||||
}
|
||||
|
||||
mNotificationBuilder.setContentText(ErrorMessageAdapter.getErrorCauseMessage(downloadResult, download, getResources()));
|
||||
mNotificationBuilder.setContentText(
|
||||
ErrorMessageAdapter.getErrorCauseMessage(downloadResult, download, getResources())
|
||||
);
|
||||
mNotificationManager.notify(tickerId, mNotificationBuilder.build());
|
||||
|
||||
// Remove success notification
|
||||
|
@ -593,38 +576,47 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
|
|||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public void cancel(Account account, OCFile file){
|
||||
DownloadFileOperation download = null;
|
||||
String targetKey = buildRemoteName(account, file);
|
||||
//String targetKey = buildKey(account, file.getRemotePath());
|
||||
ArrayList<String> keyItems = new ArrayList<String>();
|
||||
synchronized (mPendingDownloads) {
|
||||
if (file.isFolder()) {
|
||||
Log_OC.d(TAG, "Folder download. Canceling pending downloads (from folder)");
|
||||
Iterator<String> it = mPendingDownloads.keySet().iterator();
|
||||
boolean found = false;
|
||||
while (it.hasNext()) {
|
||||
String keyDownloadOperation = it.next();
|
||||
found = keyDownloadOperation.startsWith(targetKey);
|
||||
if (found) {
|
||||
keyItems.add(keyDownloadOperation);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// this is not really expected...
|
||||
Log_OC.d(TAG, "Canceling file download");
|
||||
keyItems.add(buildRemoteName(account, file));
|
||||
}
|
||||
}
|
||||
for (String item: keyItems) {
|
||||
download = mPendingDownloads.remove(item);
|
||||
Log_OC.d(TAG, "Key removed: " + item);
|
||||
if (file.isFolder()) {
|
||||
Log_OC.d(TAG, "Folder download. Canceling pending downloads (from folder)");
|
||||
|
||||
// TODO
|
||||
/*
|
||||
Iterator<String> it = mPendingDownloads.keySet().iterator();
|
||||
boolean found = false;
|
||||
while (it.hasNext()) {
|
||||
String keyDownloadOperation = it.next();
|
||||
found = keyDownloadOperation.startsWith(targetKey);
|
||||
if (found) {
|
||||
keyItems.add(keyDownloadOperation);
|
||||
}
|
||||
}
|
||||
|
||||
for (String item: keyItems) {
|
||||
download = mPendingDownloads.remove(item);
|
||||
Log_OC.d(TAG, "Key removed: " + item);
|
||||
|
||||
if (download != null) {
|
||||
download.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
} else {
|
||||
// this is not really expected...
|
||||
Log_OC.d(TAG, "Canceling file download");
|
||||
download = mPendingDownloads.remove(account, file.getRemotePath());
|
||||
if (download != null) {
|
||||
download.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
179
src/com/owncloud/android/files/services/IndexedForest.java
Normal file
179
src/com/owncloud/android/files/services/IndexedForest.java
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* ownCloud Android client application
|
||||
* Copyright (C) 2015 ownCloud Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.owncloud.android.files.services;
|
||||
|
||||
import android.accounts.Account;
|
||||
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* Helper structure to keep the trees of folders containing any file downloading or synchronizing.
|
||||
*
|
||||
* A map provides the indexation based in hashing.
|
||||
*
|
||||
* A tree is created per account.
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public class IndexedForest<V> {
|
||||
|
||||
private ConcurrentMap<String, Node<V>> mMap = new ConcurrentHashMap<String, Node<V>>();
|
||||
|
||||
private class Node<V> {
|
||||
String mKey = null;
|
||||
Node<V> mParent = null;
|
||||
Set<Node<V>> mChildren = new HashSet<Node<V>>(); // TODO be careful with hash()
|
||||
V mPayload = null;
|
||||
|
||||
// payload is optional
|
||||
public Node(String key, V payload) {
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("Argument key MUST NOT be null");
|
||||
}
|
||||
mKey = key;
|
||||
mPayload = payload;
|
||||
}
|
||||
|
||||
public Node<V> getParent() {
|
||||
return mParent;
|
||||
};
|
||||
|
||||
public Set<Node<V>> getChildren() {
|
||||
return mChildren;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return mKey;
|
||||
}
|
||||
|
||||
public V getPayload() {
|
||||
return mPayload;
|
||||
}
|
||||
|
||||
public void addChild(Node<V> child) {
|
||||
mChildren.add(child);
|
||||
child.setParent(this);
|
||||
}
|
||||
|
||||
private void setParent(Node<V> parent) {
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
public boolean hasChildren() {
|
||||
return mChildren.size() > 0;
|
||||
}
|
||||
|
||||
public void removeChild(Node<V> removed) {
|
||||
mChildren.remove(removed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public /* synchronized */ String putIfAbsent(Account account, String remotePath, V value) {
|
||||
String targetKey = buildKey(account, remotePath);
|
||||
Node<V> valuedNode = new Node(targetKey, value);
|
||||
mMap.putIfAbsent(
|
||||
targetKey,
|
||||
valuedNode
|
||||
);
|
||||
|
||||
String currentPath = remotePath, parentPath = null, parentKey = null;
|
||||
Node<V> currentNode = valuedNode, parentNode = null;
|
||||
boolean linked = false;
|
||||
while (!OCFile.ROOT_PATH.equals(currentPath) && !linked) {
|
||||
parentPath = new File(currentPath).getParent();
|
||||
if (!parentPath.endsWith(OCFile.PATH_SEPARATOR)) {
|
||||
parentPath += OCFile.PATH_SEPARATOR;
|
||||
}
|
||||
parentKey = buildKey(account, parentPath);
|
||||
parentNode = mMap.get(parentKey);
|
||||
if (parentNode == null) {
|
||||
parentNode = new Node(parentKey, null);
|
||||
parentNode.addChild(currentNode);
|
||||
mMap.put(parentKey, parentNode);
|
||||
} else {
|
||||
parentNode.addChild(currentNode);
|
||||
linked = true;
|
||||
}
|
||||
currentPath = parentPath;
|
||||
currentNode = parentNode;
|
||||
}
|
||||
|
||||
return targetKey;
|
||||
};
|
||||
|
||||
public /* synchronized */ V remove(Account account, String remotePath) {
|
||||
String targetKey = buildKey(account, remotePath);
|
||||
Node<V> firstRemoved = mMap.remove(targetKey);
|
||||
|
||||
if (firstRemoved != null) {
|
||||
Node<V> removed = firstRemoved;
|
||||
Node<V> parent = removed.getParent();
|
||||
while (parent != null) {
|
||||
parent.removeChild(removed);
|
||||
if (!parent.hasChildren()) {
|
||||
removed = mMap.remove(parent.getKey());
|
||||
parent = removed.getParent();
|
||||
} else {
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (firstRemoved != null) {
|
||||
return firstRemoved.getPayload();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean contains(Account account, String remotePath) {
|
||||
String targetKey = buildKey(account, remotePath);
|
||||
return mMap.containsKey(targetKey);
|
||||
}
|
||||
|
||||
public /* synchronized */ V get(String key) {
|
||||
Node<V> node = mMap.get(key);
|
||||
if (node != null) {
|
||||
return node.getPayload();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Builds a key to index files
|
||||
*
|
||||
* @param account Account where the file to download is stored
|
||||
* @param remotePath Path of the file in the server
|
||||
*/
|
||||
private String buildKey(Account account, String remotePath) {
|
||||
return account.name + remotePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package com.owncloud.android.services;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
@ -469,8 +470,22 @@ public class OperationsService extends Service {
|
|||
} catch (IOException e) {
|
||||
Log_OC.e(TAG, "Error while trying to get autorization", e);
|
||||
} finally {
|
||||
synchronized(mPendingOperations) {
|
||||
synchronized (mPendingOperations) {
|
||||
mPendingOperations.remove(syncKey);
|
||||
/*
|
||||
SynchronizeFolderOperation checkedOp = mCurrentSyncOperation;
|
||||
String checkedKey = syncKey;
|
||||
while (checkedOp.getPendingChildrenCount() <= 0) {
|
||||
// while (!checkedOp.hasChildren()) {
|
||||
mPendingOperations.remove(checkedKey);
|
||||
String parentKey = buildRemoteName(account, (new File(checkedOp.getFolderPath())).getParent());
|
||||
// String parentKey = buildRemoteName(account, checkedOp.getParentPath());
|
||||
SynchronizeFolderOperation parentOp = mPendingOperations.get(parentKey);
|
||||
if (parentOp != null) {
|
||||
parentOp.decreasePendingChildrenCount();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
mService.dispatchResultToOperationListeners(null, mCurrentSyncOperation, result);
|
||||
|
|
|
@ -1255,7 +1255,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
|
|||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* current folder.
|
||||
|
@ -1725,7 +1725,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
|
|||
|
||||
private void requestForDownload() {
|
||||
Account account = getAccount();
|
||||
if (mWaitingToPreview.isDownloading()) {
|
||||
//if (!mWaitingToPreview.isDownloading()) {
|
||||
if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
|
||||
Intent i = new Intent(this, FileDownloader.class);
|
||||
i.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
|
||||
i.putExtra(FileDownloader.EXTRA_FILE, mWaitingToPreview);
|
||||
|
@ -1781,9 +1782,10 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
|
|||
}
|
||||
|
||||
private void requestForDownload(OCFile file) {
|
||||
if (file.isDownloading()) {
|
||||
Account account = getAccount();
|
||||
if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
|
||||
Intent i = new Intent(this, FileDownloader.class);
|
||||
i.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());
|
||||
i.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
|
||||
i.putExtra(FileDownloader.EXTRA_FILE, file);
|
||||
startService(i);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import com.owncloud.android.authentication.AccountUtils;
|
|||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
|
||||
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
|
||||
import com.owncloud.android.ui.activity.ComponentsGetter;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
|
@ -151,8 +152,10 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
|
|||
|
||||
ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);
|
||||
localStateView.bringToFront();
|
||||
FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder();
|
||||
FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder();
|
||||
if (file.isSynchronizing() || file.isDownloading()) {
|
||||
//if (file.isSynchronizing() || file.isDownloading()) {
|
||||
if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) {
|
||||
localStateView.setImageResource(R.drawable.downloading_file_indicator);
|
||||
localStateView.setVisibility(View.VISIBLE);
|
||||
} else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) {
|
||||
|
|
|
@ -346,8 +346,12 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
|
|||
cb.setChecked(file.keepInSync());
|
||||
|
||||
// configure UI for depending upon local state of the file
|
||||
FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();
|
||||
FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();
|
||||
if (transferring || file.isDownloading() || uploaderBinder.isUploading(mAccount, file)) {
|
||||
if (transferring ||
|
||||
(downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file)) ||
|
||||
(uploaderBinder != null && uploaderBinder.isUploading(mAccount, file))
|
||||
) {
|
||||
setButtonsForTransferring();
|
||||
|
||||
} else if (file.isDown()) {
|
||||
|
@ -446,8 +450,10 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
|
|||
getView().findViewById(R.id.fdProgressBlock).setVisibility(View.VISIBLE);
|
||||
TextView progressText = (TextView)getView().findViewById(R.id.fdProgressText);
|
||||
progressText.setVisibility(View.VISIBLE);
|
||||
FileDownloaderBinder downloaderBinder = mContainerActivity.getFileDownloaderBinder();
|
||||
FileUploaderBinder uploaderBinder = mContainerActivity.getFileUploaderBinder();
|
||||
if (getFile().isDownloading()) {
|
||||
//if (getFile().isDownloading()) {
|
||||
if (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, getFile())) {
|
||||
progressText.setText(R.string.downloader_download_in_progress_ticker);
|
||||
} else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, getFile())) {
|
||||
progressText.setText(R.string.uploader_upload_in_progress_ticker);
|
||||
|
|
|
@ -365,7 +365,7 @@ ViewPager.OnPageChangeListener, OnRemoteOperationListener {
|
|||
if (mDownloaderBinder == null) {
|
||||
Log_OC.d(TAG, "requestForDownload called without binder to download service");
|
||||
|
||||
} else if (!file.isDownloading()) {
|
||||
} else if (!mDownloaderBinder.isDownloading(getAccount(), file)) {
|
||||
Intent i = new Intent(this, FileDownloader.class);
|
||||
i.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());
|
||||
i.putExtra(FileDownloader.EXTRA_FILE, file);
|
||||
|
|
Loading…
Reference in a new issue