mirror of
https://github.com/nextcloud/android.git
synced 2024-11-23 13:45:35 +03:00
Clean up of synchronization code
This commit is contained in:
parent
8a27bf186a
commit
23c9be24a2
7 changed files with 387 additions and 308 deletions
|
@ -126,7 +126,7 @@ public class FileDataStorageManager implements DataStorageManager {
|
|||
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
|
||||
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
|
||||
cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
|
||||
if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID)
|
||||
//if (file.getParentId() != DataStorageManager.ROOT_PARENT_ID)
|
||||
cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
|
||||
cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
|
||||
if (!file.isDirectory())
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -50,7 +49,13 @@ import eu.alefzero.webdav.WebdavUtils;
|
|||
|
||||
|
||||
/**
|
||||
* Remote operation performing the synchronization a the contents of a remote folder with the local database
|
||||
* Remote operation performing the synchronization of the list of files contained
|
||||
* in a folder identified with its remote path.
|
||||
*
|
||||
* Fetches the list and properties of the files contained in the given folder, including their
|
||||
* properties, and updates the local database with them.
|
||||
*
|
||||
* Does NOT enter in the child folders to synchronize their contents also.
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
|
@ -58,17 +63,15 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
|
||||
private static final String TAG = SynchronizeFolderOperation.class.getSimpleName();
|
||||
|
||||
/** Remote folder to synchronize */
|
||||
private String mRemotePath;
|
||||
|
||||
/** Timestamp for the synchronization in progress */
|
||||
/** Time stamp for the synchronization process in progress */
|
||||
private long mCurrentSyncTime;
|
||||
|
||||
/** Id of the folder to synchronize in the local database */
|
||||
private long mParentId;
|
||||
/** Remote folder to synchronize */
|
||||
private OCFile mLocalFolder;
|
||||
|
||||
/** Boolean to indicate if is mandatory to update the folder */
|
||||
private boolean mEnforceMetadataUpdate;
|
||||
/** 'True' means that the properties of the folder should be updated also, not just its content */
|
||||
private boolean mUpdateFolderProperties;
|
||||
|
||||
/** Access to the local database */
|
||||
private DataStorageManager mStorageManager;
|
||||
|
@ -76,33 +79,47 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
/** Account where the file to synchronize belongs */
|
||||
private Account mAccount;
|
||||
|
||||
/** Android context; necessary to send requests to the download service; maybe something to refactor */
|
||||
/** Android context; necessary to send requests to the download service */
|
||||
private Context mContext;
|
||||
|
||||
/** Files and folders contained in the synchronized folder */
|
||||
/** Files and folders contained in the synchronized folder after a successful operation */
|
||||
private List<OCFile> mChildren;
|
||||
|
||||
/** Counter of conflicts found between local and remote files */
|
||||
private int mConflictsFound;
|
||||
|
||||
/** Counter of failed operations in synchronization of kept-in-sync files */
|
||||
private int mFailsInFavouritesFound;
|
||||
|
||||
/** Map of remote and local paths to files that where locally stored in a location out of the ownCloud folder and couldn't be copied automatically into it */
|
||||
private Map<String, String> mForgottenLocalFiles;
|
||||
|
||||
/** 'True' means that this operation is part of a full account synchronization */
|
||||
private boolean mSyncFullAccount;
|
||||
|
||||
|
||||
public SynchronizeFolderOperation( String remotePath,
|
||||
/**
|
||||
* Creates a new instance of {@link SynchronizeFolderOperation}.
|
||||
*
|
||||
* @param remoteFolderPath Remote folder to synchronize.
|
||||
* @param currentSyncTime Time stamp for the synchronization process in progress.
|
||||
* @param localFolderId Identifier in the local database of the folder to synchronize.
|
||||
* @param updateFolderProperties 'True' means that the properties of the folder should be updated also, not just its content.
|
||||
* @param syncFullAccount 'True' means that this operation is part of a full account synchronization.
|
||||
* @param dataStorageManager Interface with the local database.
|
||||
* @param account ownCloud account where the folder is located.
|
||||
* @param context Application context.
|
||||
*/
|
||||
public SynchronizeFolderOperation( OCFile folder,
|
||||
long currentSyncTime,
|
||||
long parentId,
|
||||
boolean enforceMetadataUpdate,
|
||||
boolean updateFolderProperties,
|
||||
boolean syncFullAccount,
|
||||
DataStorageManager dataStorageManager,
|
||||
Account account,
|
||||
Context context ) {
|
||||
mRemotePath = remotePath;
|
||||
mLocalFolder = folder;
|
||||
mCurrentSyncTime = currentSyncTime;
|
||||
mParentId = parentId;
|
||||
mEnforceMetadataUpdate = enforceMetadataUpdate;
|
||||
mUpdateFolderProperties = updateFolderProperties;
|
||||
mSyncFullAccount = syncFullAccount;
|
||||
mStorageManager = dataStorageManager;
|
||||
mAccount = account;
|
||||
|
@ -132,99 +149,147 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
return mChildren;
|
||||
}
|
||||
|
||||
public String getRemotePath() {
|
||||
return mRemotePath;
|
||||
}
|
||||
|
||||
public long getParentId() {
|
||||
return mParentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the synchronization.
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected RemoteOperationResult run(WebdavClient client) {
|
||||
RemoteOperationResult result = null;
|
||||
mFailsInFavouritesFound = 0;
|
||||
mConflictsFound = 0;
|
||||
mForgottenLocalFiles.clear();
|
||||
boolean dirChanged = false;
|
||||
|
||||
// code before in FileSyncAdapter.fetchData
|
||||
String remotePath = null;
|
||||
PropFindMethod query = null;
|
||||
try {
|
||||
Log_OC.d(TAG, "Synchronizing " + mAccount.name + ", fetching files in " + mRemotePath);
|
||||
remotePath = mLocalFolder.getRemotePath();
|
||||
Log_OC.d(TAG, "Synchronizing " + mAccount.name + remotePath);
|
||||
|
||||
// remote request
|
||||
query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
|
||||
query = new PropFindMethod(client.getBaseUri() + WebdavUtils.encodePath(remotePath));
|
||||
int status = client.executeMethod(query);
|
||||
|
||||
// check and process response - /// TODO take into account all the possible status per child-resource
|
||||
// check and process response
|
||||
if (isMultiStatus(status)) {
|
||||
MultiStatus resp = query.getResponseBodyAsMultiStatus();
|
||||
|
||||
// synchronize properties of the parent folder, if necessary
|
||||
WebdavEntry we = new WebdavEntry(resp.getResponses()[0], client.getBaseUri().getPath());
|
||||
|
||||
// Properties of server folder
|
||||
OCFile parent = fillOCFile(we);
|
||||
// Properties of local folder
|
||||
OCFile localParent = mStorageManager.getFileByPath(mRemotePath);
|
||||
if (localParent == null || !(parent.getEtag().equalsIgnoreCase(localParent.getEtag())) || mEnforceMetadataUpdate) {
|
||||
if (localParent != null) {
|
||||
parent.setParentId(localParent.getParentId());
|
||||
boolean folderChanged = synchronizeData(query.getResponseBodyAsMultiStatus(), client);
|
||||
if (folderChanged) {
|
||||
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
|
||||
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job
|
||||
} else {
|
||||
result = new RemoteOperationResult(true, status, query.getResponseHeaders());
|
||||
}
|
||||
mStorageManager.saveFile(parent);
|
||||
if (mParentId == DataStorageManager.ROOT_PARENT_ID)
|
||||
mParentId = parent.getFileId();
|
||||
dirChanged = true;
|
||||
} else {
|
||||
result = new RemoteOperationResult(ResultCode.OK_NO_CHANGES_ON_DIR);
|
||||
}
|
||||
|
||||
if (dirChanged) {
|
||||
// read contents in folder
|
||||
List<String> filesOnServer = new ArrayList<String> (); // Contains the lists of files on server
|
||||
List<OCFile> updatedFiles = new Vector<OCFile>(resp.getResponses().length - 1);
|
||||
} else {
|
||||
// synchronization failed
|
||||
client.exhaustResponse(query.getResponseBodyAsStream());
|
||||
if (status == HttpStatus.SC_NOT_FOUND) {
|
||||
if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
|
||||
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
|
||||
mStorageManager.removeDirectory(mLocalFolder, true, (mLocalFolder.isDown() && mLocalFolder.getStoragePath().startsWith(currentSavePath)));
|
||||
}
|
||||
}
|
||||
result = new RemoteOperationResult(false, status, query.getResponseHeaders());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
|
||||
|
||||
} finally {
|
||||
if (query != null)
|
||||
query.releaseConnection(); // let the connection available for other methods
|
||||
if (result.isSuccess()) {
|
||||
Log_OC.i(TAG, "Synchronized " + mAccount.name + remotePath + ": " + result.getLogMessage());
|
||||
} else {
|
||||
if (result.isException()) {
|
||||
Log_OC.e(TAG, "Synchroned " + mAccount.name + remotePath + ": " + result.getLogMessage(), result.getException());
|
||||
} else {
|
||||
Log_OC.e(TAG, "Synchroned " + mAccount.name + remotePath + ": " + result.getLogMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!mSyncFullAccount) {
|
||||
sendStickyBroadcast(false, remotePath, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Synchronizes the data retrieved from the server about the contents of the target folder
|
||||
* with the current data in the local database.
|
||||
*
|
||||
* Grants that mChildren is updated with fresh data after execution.
|
||||
*
|
||||
* @param dataInServer Full response got from the server with the data of the target
|
||||
* folder and its direct children.
|
||||
* @param client Client instance to the remote server where the data were
|
||||
* retrieved.
|
||||
* @return 'True' when any change was made in the local data, 'false' otherwise.
|
||||
*/
|
||||
private boolean synchronizeData(MultiStatus dataInServer, WebdavClient client) {
|
||||
// get 'fresh data' from the database
|
||||
mLocalFolder = mStorageManager.getFileById(mLocalFolder.getFileId());
|
||||
|
||||
// parse data from remote folder
|
||||
WebdavEntry we = new WebdavEntry(dataInServer.getResponses()[0], client.getBaseUri().getPath());
|
||||
OCFile remoteFolder = fillOCFile(we);
|
||||
remoteFolder.setParentId(mLocalFolder.getParentId());
|
||||
remoteFolder.setFileId(mLocalFolder.getFileId());
|
||||
|
||||
// check if remote and local folder are different
|
||||
boolean folderChanged = !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag()));
|
||||
|
||||
if (!folderChanged) {
|
||||
if (mUpdateFolderProperties) { // TODO check if this is really necessary
|
||||
mStorageManager.saveFile(remoteFolder);
|
||||
}
|
||||
|
||||
mChildren = mStorageManager.getDirectoryContent(mLocalFolder);
|
||||
|
||||
} else {
|
||||
// read info of folder contents
|
||||
List<OCFile> updatedFiles = new Vector<OCFile>(dataInServer.getResponses().length - 1);
|
||||
List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
|
||||
for (int i = 1; i < resp.getResponses().length; ++i) {
|
||||
|
||||
// loop to update every child
|
||||
OCFile remoteFile = null, localFile = null;
|
||||
for (int i = 1; i < dataInServer.getResponses().length; ++i) {
|
||||
/// new OCFile instance with the data from the server
|
||||
we = new WebdavEntry(resp.getResponses()[i], client.getBaseUri().getPath());
|
||||
OCFile file = fillOCFile(we);
|
||||
we = new WebdavEntry(dataInServer.getResponses()[i], client.getBaseUri().getPath());
|
||||
remoteFile = fillOCFile(we);
|
||||
remoteFile.setParentId(mLocalFolder.getFileId());
|
||||
|
||||
filesOnServer.add(file.getRemotePath()); // Registry the file in the list
|
||||
/// retrieve local data for the read file
|
||||
localFile = mStorageManager.getFileByPath(remoteFile.getRemotePath());
|
||||
|
||||
/// set data about local state, keeping unchanged former data if existing
|
||||
file.setLastSyncDateForProperties(mCurrentSyncTime);
|
||||
OCFile oldFile = mStorageManager.getFileByPath(file.getRemotePath());
|
||||
|
||||
// Check if it is needed to synchronize the folder
|
||||
if (oldFile != null) {
|
||||
if (!file.getEtag().equalsIgnoreCase(oldFile.getEtag())) {
|
||||
}
|
||||
/// add to the remoteFile (the new one) data about LOCAL STATE (not existing in the server side)
|
||||
remoteFile.setLastSyncDateForProperties(mCurrentSyncTime);
|
||||
if (localFile != null) {
|
||||
// properties of local state are kept unmodified
|
||||
remoteFile.setKeepInSync(localFile.keepInSync());
|
||||
remoteFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
|
||||
remoteFile.setModificationTimestampAtLastSyncForData(localFile.getModificationTimestampAtLastSyncForData());
|
||||
remoteFile.setStoragePath(localFile.getStoragePath());
|
||||
remoteFile.setEtag(localFile.getEtag()); // eTag will not be updated unless contents are synchronized (Synchronize[File|Folder]Operation with remoteFile as parameter)
|
||||
} else {
|
||||
remoteFile.setEtag(""); // remote eTag will not be updated unless contents are synchronized (Synchronize[File|Folder]Operation with remoteFile as parameter)
|
||||
}
|
||||
|
||||
if (oldFile != null) {
|
||||
file.setKeepInSync(oldFile.keepInSync());
|
||||
file.setLastSyncDateForData(oldFile.getLastSyncDateForData());
|
||||
file.setModificationTimestampAtLastSyncForData(oldFile.getModificationTimestampAtLastSyncForData()); // must be kept unchanged when the file contents are not updated
|
||||
checkAndFixForeignStoragePath(oldFile);
|
||||
file.setStoragePath(oldFile.getStoragePath());
|
||||
if (file.isDirectory())
|
||||
file.setEtag(oldFile.getEtag());
|
||||
} else
|
||||
if (file.isDirectory())
|
||||
file.setEtag("");
|
||||
|
||||
/// scan default location if local copy of file is not linked in OCFile instance
|
||||
if (file.getStoragePath() == null && !file.isDirectory()) {
|
||||
File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
|
||||
if (f.exists()) {
|
||||
file.setStoragePath(f.getAbsolutePath());
|
||||
file.setLastSyncDateForData(f.lastModified());
|
||||
}
|
||||
}
|
||||
/// check and fix, if need, local storage path
|
||||
checkAndFixForeignStoragePath(remoteFile); // fixing old policy - now local files must be copied into the ownCloud local folder
|
||||
searchForLocalFileInDefaultPath(remoteFile); // legacy
|
||||
|
||||
/// prepare content synchronization for kept-in-sync files
|
||||
if (file.keepInSync()) {
|
||||
SynchronizeFileOperation operation = new SynchronizeFileOperation( oldFile,
|
||||
file,
|
||||
if (remoteFile.keepInSync()) {
|
||||
SynchronizeFileOperation operation = new SynchronizeFileOperation( localFile,
|
||||
remoteFile,
|
||||
mStorageManager,
|
||||
mAccount,
|
||||
true,
|
||||
|
@ -234,13 +299,58 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
filesToSyncContents.add(operation);
|
||||
}
|
||||
|
||||
updatedFiles.add(file);
|
||||
updatedFiles.add(remoteFile);
|
||||
}
|
||||
|
||||
// save updated contents in local database; all at once, trying to get a best performance in database update (not a big deal, indeed)
|
||||
mStorageManager.saveFiles(updatedFiles);
|
||||
|
||||
// request for the synchronization of files AFTER saving last properties
|
||||
// request for the synchronization of file contents AFTER saving current remote properties
|
||||
startContentSynchronizations(filesToSyncContents, client);
|
||||
|
||||
// removal of obsolete files
|
||||
removeObsoleteFiles();
|
||||
|
||||
// must be done AFTER saving all the children information, so that eTag is not updated in the database in case of unexpected exceptions
|
||||
mStorageManager.saveFile(remoteFolder);
|
||||
|
||||
}
|
||||
|
||||
return folderChanged;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes obsolete children in the folder after saving all the new data.
|
||||
*/
|
||||
private void removeObsoleteFiles() {
|
||||
mChildren = mStorageManager.getDirectoryContent(mLocalFolder);
|
||||
OCFile file;
|
||||
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
|
||||
for (int i=0; i < mChildren.size(); ) {
|
||||
file = mChildren.get(i);
|
||||
if (file.getLastSyncDateForProperties() != mCurrentSyncTime) {
|
||||
Log_OC.d(TAG, "removing file: " + file);
|
||||
mStorageManager.removeFile(file, (file.isDown() && file.getStoragePath().startsWith(currentSavePath)));
|
||||
mChildren.remove(i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a list of synchronization operations, determining if a download or upload is needed or
|
||||
* if exists conflict due to changes both in local and remote contents of the each file.
|
||||
*
|
||||
* If download or upload is needed, request the operation to the corresponding service and goes on.
|
||||
*
|
||||
* @param filesToSyncContents Synchronization operations to execute.
|
||||
* @param client Interface to the remote ownCloud server.
|
||||
*/
|
||||
private void startContentSynchronizations(List<SynchronizeFileOperation> filesToSyncContents, WebdavClient client) {
|
||||
RemoteOperationResult contentsResult = null;
|
||||
for (SynchronizeFileOperation op: filesToSyncContents) {
|
||||
contentsResult = op.execute(client); // returns without waiting for upload or download finishes
|
||||
|
@ -257,75 +367,6 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
}
|
||||
} // won't let these fails break the synchronization process
|
||||
}
|
||||
|
||||
// removal of obsolete files
|
||||
mChildren = mStorageManager.getDirectoryContent(mStorageManager.getFileById(mParentId));
|
||||
OCFile file;
|
||||
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
|
||||
for (int i=0; i < mChildren.size(); ) {
|
||||
file = mChildren.get(i);
|
||||
if (file.getLastSyncDateForProperties() != mCurrentSyncTime) {
|
||||
Log_OC.d(TAG, "removing file: " + file);
|
||||
mStorageManager.removeFile(file, (file.isDown() && file.getStoragePath().startsWith(currentSavePath)));
|
||||
mChildren.remove(i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
client.exhaustResponse(query.getResponseBodyAsStream());
|
||||
}
|
||||
|
||||
|
||||
// prepare result object
|
||||
if (!dirChanged) {
|
||||
result = new RemoteOperationResult(ResultCode.OK_NO_CHANGES_ON_DIR);
|
||||
mChildren = mStorageManager.getDirectoryContent(mStorageManager.getFileById(mParentId));
|
||||
|
||||
} else {
|
||||
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
|
||||
result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job
|
||||
|
||||
} else {
|
||||
result = new RemoteOperationResult(true, status, query.getResponseHeaders());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (status == HttpStatus.SC_NOT_FOUND) {
|
||||
OCFile dir = mStorageManager.getFileByPath(mRemotePath);
|
||||
if (dir != null) {
|
||||
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
|
||||
mStorageManager.removeDirectory(dir, true, (dir.isDown() && dir.getStoragePath().startsWith(currentSavePath)));
|
||||
}
|
||||
}
|
||||
result = new RemoteOperationResult(false, status, query.getResponseHeaders());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
result = new RemoteOperationResult(e);
|
||||
|
||||
|
||||
} finally {
|
||||
if (query != null)
|
||||
query.releaseConnection(); // let the connection available for other methods
|
||||
if (result.isSuccess()) {
|
||||
Log_OC.i(TAG, "Synchroned " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage());
|
||||
} else {
|
||||
if (result.isException()) {
|
||||
Log_OC.e(TAG, "Synchroned " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage(), result.getException());
|
||||
} else {
|
||||
Log_OC.e(TAG, "Synchroned " + mAccount.name + ", folder " + mRemotePath + ": " + result.getLogMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (!mSyncFullAccount) {
|
||||
sendStickyBroadcast(false, mRemotePath, result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -346,7 +387,6 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
file.setFileLength(we.contentLength());
|
||||
file.setMimetype(we.contentType());
|
||||
file.setModificationTimestamp(we.modifiedTimestamp());
|
||||
file.setParentId(mParentId);
|
||||
file.setEtag(we.etag());
|
||||
return file;
|
||||
}
|
||||
|
@ -415,6 +455,25 @@ public class SynchronizeFolderOperation extends RemoteOperation {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Scans the default location for saving local copies of files searching for
|
||||
* a 'lost' file with the same full name as the {@link OCFile} received as
|
||||
* parameter.
|
||||
*
|
||||
* @param file File to associate a possible 'lost' local file.
|
||||
*/
|
||||
private void searchForLocalFileInDefaultPath(OCFile file) {
|
||||
if (file.getStoragePath() == null && !file.isDirectory()) {
|
||||
File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
|
||||
if (f.exists()) {
|
||||
file.setStoragePath(f.getAbsolutePath());
|
||||
file.setLastSyncDateForData(f.lastModified());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends a message to any application component interested in the progress of the synchronization.
|
||||
*
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
package com.owncloud.android.syncadapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Date;
|
||||
//import java.net.UnknownHostException;
|
||||
//import java.util.Date;
|
||||
|
||||
import org.apache.http.HttpRequest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
//import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
||||
//import org.apache.http.protocol.HttpContext;
|
||||
|
||||
import com.owncloud.android.authentication.AccountUtils;
|
||||
import com.owncloud.android.authentication.AccountUtils.AccountNotFoundException;
|
||||
|
@ -43,11 +43,13 @@ import android.content.Context;
|
|||
import eu.alefzero.webdav.WebdavClient;
|
||||
|
||||
/**
|
||||
* Base SyncAdapter for OwnCloud Designed to be subclassed for the concrete
|
||||
* SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..
|
||||
* Base synchronization adapter for ownCloud designed to be subclassed for different
|
||||
* resource types, like FileSync, ConcatsSync, CalendarSync, etc..
|
||||
*
|
||||
* Implements the standard {@link AbstractThreadedSyncAdapter}.
|
||||
*
|
||||
* @author sassman
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public abstract class AbstractOwnCloudSyncAdapter extends
|
||||
AbstractThreadedSyncAdapter {
|
||||
|
@ -55,7 +57,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
|
|||
private AccountManager accountManager;
|
||||
private Account account;
|
||||
private ContentProviderClient contentProvider;
|
||||
private Date lastUpdated;
|
||||
//private Date lastUpdated;
|
||||
private DataStorageManager mStoreManager;
|
||||
|
||||
private WebdavClient mClient = null;
|
||||
|
@ -89,14 +91,6 @@ public abstract class AbstractOwnCloudSyncAdapter extends
|
|||
this.contentProvider = contentProvider;
|
||||
}
|
||||
|
||||
public Date getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
|
||||
public void setLastUpdated(Date lastUpdated) {
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
||||
public void setStorageManager(DataStorageManager storage_manager) {
|
||||
mStoreManager = storage_manager;
|
||||
}
|
||||
|
@ -105,6 +99,41 @@ public abstract class AbstractOwnCloudSyncAdapter extends
|
|||
return mStoreManager;
|
||||
}
|
||||
|
||||
protected void initClientForCurrentAccount() throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException {
|
||||
AccountUtils.constructFullURLForAccount(getContext(), account);
|
||||
mClient = OwnCloudClientUtils.createOwnCloudClient(account, getContext());
|
||||
}
|
||||
|
||||
protected WebdavClient getClient() {
|
||||
return mClient;
|
||||
}
|
||||
|
||||
|
||||
/* method called by ContactSyncAdapter, that is never used */
|
||||
protected HttpResponse fireRawRequest(HttpRequest query)
|
||||
throws ClientProtocolException, OperationCanceledException,
|
||||
AuthenticatorException, IOException {
|
||||
/*
|
||||
* BasicHttpContext httpContext = new BasicHttpContext(); BasicScheme
|
||||
* basicAuth = new BasicScheme();
|
||||
* httpContext.setAttribute("preemptive-auth", basicAuth);
|
||||
*
|
||||
* HttpResponse response = getClient().execute(mHost, query,
|
||||
* httpContext);
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
/* methods never used below */
|
||||
/*
|
||||
public Date getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
|
||||
public void setLastUpdated(Date lastUpdated) {
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
||||
protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {
|
||||
return new ConnectionKeepAliveStrategy() {
|
||||
public long getKeepAliveDuration(HttpResponse response,
|
||||
|
@ -128,27 +157,5 @@ public abstract class AbstractOwnCloudSyncAdapter extends
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected HttpResponse fireRawRequest(HttpRequest query)
|
||||
throws ClientProtocolException, OperationCanceledException,
|
||||
AuthenticatorException, IOException {
|
||||
/*
|
||||
* BasicHttpContext httpContext = new BasicHttpContext(); BasicScheme
|
||||
* basicAuth = new BasicScheme();
|
||||
* httpContext.setAttribute("preemptive-auth", basicAuth);
|
||||
*
|
||||
* HttpResponse response = getClient().execute(mHost, query,
|
||||
* httpContext);
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void initClientForCurrentAccount() throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException {
|
||||
AccountUtils.constructFullURLForAccount(getContext(), account);
|
||||
mClient = OwnCloudClientUtils.createOwnCloudClient(account, getContext());
|
||||
}
|
||||
|
||||
protected WebdavClient getClient() {
|
||||
return mClient;
|
||||
}
|
||||
}
|
|
@ -30,7 +30,6 @@ import com.owncloud.android.Log_OC;
|
|||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AccountAuthenticator;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
import com.owncloud.android.datamodel.DataStorageManager;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.operations.RemoteOperationResult;
|
||||
|
@ -44,6 +43,7 @@ import android.accounts.AccountsException;
|
|||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.AbstractThreadedSyncAdapter;
|
||||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
@ -52,36 +52,60 @@ import android.content.SyncResult;
|
|||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* SyncAdapter implementation for syncing sample SyncAdapter contacts to the
|
||||
* platform ContactOperations provider.
|
||||
* Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing
|
||||
* ownCloud files.
|
||||
*
|
||||
* Performs a full synchronization of the account recieved in {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}.
|
||||
*
|
||||
* @author Bartek Przybylski
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
||||
|
||||
private final static String TAG = "FileSyncAdapter";
|
||||
private final static String TAG = FileSyncAdapter.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Maximum number of failed folder synchronizations that are supported before finishing the synchronization operation
|
||||
*/
|
||||
/** Maximum number of failed folder synchronizations that are supported before finishing the synchronization operation */
|
||||
private static final int MAX_FAILED_RESULTS = 3;
|
||||
|
||||
|
||||
/** Time stamp for the current synchronization process, used to distinguish fresh data */
|
||||
private long mCurrentSyncTime;
|
||||
|
||||
/** Flag made 'true' when a request to cancel the synchronization is received */
|
||||
private boolean mCancellation;
|
||||
|
||||
/** When 'true' the process was requested by the user through the user interface; when 'false', it was requested automatically by the system */
|
||||
private boolean mIsManualSync;
|
||||
|
||||
/** Counter for failed operations in the synchronization process */
|
||||
private int mFailedResultsCounter;
|
||||
|
||||
/** Result of the last failed operation */
|
||||
private RemoteOperationResult mLastFailedResult;
|
||||
private SyncResult mSyncResult;
|
||||
|
||||
/** Counter of conflicts found between local and remote files */
|
||||
private int mConflictsFound;
|
||||
|
||||
/** Counter of failed operations in synchronization of kept-in-sync files */
|
||||
private int mFailsInFavouritesFound;
|
||||
|
||||
/** Map of remote and local paths to files that where locally stored in a location out of the ownCloud folder and couldn't be copied automatically into it */
|
||||
private Map<String, String> mForgottenLocalFiles;
|
||||
|
||||
/** {@link SyncResult} instance to return to the system when the synchronization finish */
|
||||
private SyncResult mSyncResult;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an {@link FileSyncAdapter}
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public FileSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -99,20 +123,20 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
mForgottenLocalFiles = new HashMap<String, String>();
|
||||
mSyncResult = syncResult;
|
||||
mSyncResult.fullSyncRequested = false;
|
||||
mSyncResult.delayUntil = 60*60*24; // sync after 24h
|
||||
mSyncResult.delayUntil = 60*60*24; // avoid too many automatic synchronizations
|
||||
|
||||
this.setAccount(account);
|
||||
this.setContentProvider(provider);
|
||||
this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));
|
||||
this.setStorageManager(new FileDataStorageManager(account, provider));
|
||||
try {
|
||||
this.initClientForCurrentAccount();
|
||||
} catch (IOException e) {
|
||||
/// the account is unknown for the Synchronization Manager, or unreachable for this context; don't try this again
|
||||
/// the account is unknown for the Synchronization Manager, unreachable this context, or can not be authenticated; don't try this again
|
||||
mSyncResult.tooManyRetries = true;
|
||||
notifyFailedSynchronization();
|
||||
return;
|
||||
} catch (AccountsException e) {
|
||||
/// the account is unknown for the Synchronization Manager, or unreachable for this context; don't try this again
|
||||
/// the account is unknown for the Synchronization Manager, unreachable this context, or can not be authenticated; don't try this again
|
||||
mSyncResult.tooManyRetries = true;
|
||||
notifyFailedSynchronization();
|
||||
return;
|
||||
|
@ -125,10 +149,10 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
updateOCVersion();
|
||||
mCurrentSyncTime = System.currentTimeMillis();
|
||||
if (!mCancellation) {
|
||||
fetchData(OCFile.PATH_SEPARATOR, DataStorageManager.ROOT_PARENT_ID);
|
||||
synchronizeFolder(getStorageManager().getFileByPath(OCFile.PATH_SEPARATOR), true);
|
||||
|
||||
} else {
|
||||
Log_OC.d(TAG, "Leaving synchronization before any remote request due to cancellation was requested");
|
||||
Log_OC.d(TAG, "Leaving synchronization before synchronizing the root folder because cancelation request");
|
||||
}
|
||||
|
||||
|
||||
|
@ -142,14 +166,12 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
|
||||
/// notify the user about the failure of MANUAL synchronization
|
||||
notifyFailedSynchronization();
|
||||
|
||||
}
|
||||
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
|
||||
notifyFailsInFavourites();
|
||||
}
|
||||
if (mForgottenLocalFiles.size() > 0) {
|
||||
notifyForgottenLocalFiles();
|
||||
|
||||
}
|
||||
sendStickyBroadcast(false, null, mLastFailedResult); // message to signal the end to the UI
|
||||
}
|
||||
|
@ -159,8 +181,12 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
/**
|
||||
* Called by system SyncManager when a synchronization is required to be cancelled.
|
||||
*
|
||||
* Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder
|
||||
* fetched will be still saved in the database. See onPerformSync implementation.
|
||||
* Sets the mCancellation flag to 'true'. THe synchronization will be stopped later,
|
||||
* before a new folder is fetched. Data of the last folder synchronized will be still
|
||||
* locally saved.
|
||||
*
|
||||
* See {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}
|
||||
* and {@link #synchronizeFolder(String, long)}.
|
||||
*/
|
||||
@Override
|
||||
public void onSyncCanceled() {
|
||||
|
@ -183,23 +209,37 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
|
||||
|
||||
/**
|
||||
* Synchronize the properties of files and folders contained in a remote folder given by remotePath.
|
||||
* Synchronizes the list of files contained in a folder identified with its remote path.
|
||||
*
|
||||
* @param remotePath Remote path to the folder to synchronize.
|
||||
* @param parentId Database Id of the folder to synchronize.
|
||||
* Fetches the list and properties of the files contained in the given folder, including their
|
||||
* properties, and updates the local database with them.
|
||||
*
|
||||
* Enters in the child folders to synchronize their contents also, following a recursive
|
||||
* depth first strategy.
|
||||
*
|
||||
* @param folder Folder to synchronize.
|
||||
* @param updateFolderProperties When 'true', updates also the properties of the of the target folder.
|
||||
*/
|
||||
private void fetchData(String remotePath, long parentId) {
|
||||
private void synchronizeFolder(OCFile folder, boolean updateFolderProperties) {
|
||||
|
||||
if (mFailedResultsCounter > MAX_FAILED_RESULTS || isFinisher(mLastFailedResult))
|
||||
return;
|
||||
|
||||
boolean enforceMetadataUpdate = (parentId == DataStorageManager.ROOT_PARENT_ID);
|
||||
/*
|
||||
OCFile folder,
|
||||
long currentSyncTime,
|
||||
boolean updateFolderProperties,
|
||||
boolean syncFullAccount,
|
||||
DataStorageManager dataStorageManager,
|
||||
Account account,
|
||||
Context context ) {
|
||||
|
||||
// perform folder synchronization
|
||||
SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( remotePath,
|
||||
}
|
||||
*/
|
||||
// folder synchronization
|
||||
SynchronizeFolderOperation synchFolderOp = new SynchronizeFolderOperation( folder,
|
||||
mCurrentSyncTime,
|
||||
parentId,
|
||||
enforceMetadataUpdate,
|
||||
updateFolderProperties,
|
||||
true,
|
||||
getStorageManager(),
|
||||
getAccount(),
|
||||
|
@ -209,8 +249,9 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
|
||||
|
||||
// synchronized folder -> notice to UI - ALWAYS, although !result.isSuccess
|
||||
sendStickyBroadcast(true, remotePath, null);
|
||||
sendStickyBroadcast(true, folder.getRemotePath(), null);
|
||||
|
||||
// check the result of synchronizing the folder
|
||||
if (result.isSuccess() || result.getCode() == ResultCode.SYNC_CONFLICT) {
|
||||
|
||||
if (result.getCode() == ResultCode.SYNC_CONFLICT) {
|
||||
|
@ -224,11 +265,13 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
List<OCFile> children = synchFolderOp.getChildren();
|
||||
fetchChildren(children); // beware of the 'hidden' recursion here!
|
||||
|
||||
sendStickyBroadcast(true, remotePath, null);
|
||||
// update folder size again after recursive synchronization
|
||||
getStorageManager().calculateFolderSize(folder.getFileId());
|
||||
sendStickyBroadcast(true, folder.getRemotePath(), null); // notify again
|
||||
|
||||
} else {
|
||||
// in failures, the statistics for the global result are updated
|
||||
if (result.getCode() == RemoteOperationResult.ResultCode.UNAUTHORIZED ||
|
||||
// (result.isTemporalRedirection() && result.isIdPRedirection() &&
|
||||
( result.isIdPRedirection() &&
|
||||
AccountAuthenticator.AUTH_TOKEN_TYPE_SAML_WEB_SSO_SESSION_COOKIE.equals(getClient().getAuthTokenType()))) {
|
||||
mSyncResult.stats.numAuthExceptions++;
|
||||
|
@ -264,23 +307,20 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Synchronize data of folders in the list of received files
|
||||
* Triggers the synchronization of any folder contained in the list of received files.
|
||||
*
|
||||
* @param files Files to recursively fetch
|
||||
* @param files Files to recursively synchronize.
|
||||
*/
|
||||
private void fetchChildren(List<OCFile> files) {
|
||||
int i;
|
||||
for (i=0; i < files.size() && !mCancellation; i++) {
|
||||
OCFile newFile = files.get(i);
|
||||
if (newFile.isDirectory()) {
|
||||
fetchData(newFile.getRemotePath(), newFile.getFileId());
|
||||
|
||||
// Update folder size on DB
|
||||
getStorageManager().calculateFolderSize(newFile.getFileId());
|
||||
synchronizeFolder(newFile, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mCancellation && i <files.size()) Log_OC.d(TAG, "Leaving synchronization before synchronizing " + files.get(i).getRemotePath() + " because cancelation request");
|
||||
if (mCancellation && i <files.size()) Log_OC.d(TAG, "Leaving synchronization before synchronizing " + files.get(i).getRemotePath() + " due to cancelation request");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,12 +22,15 @@ import android.content.Intent;
|
|||
import android.os.IBinder;
|
||||
|
||||
/**
|
||||
* Background service for syncing files to our local Database
|
||||
* Background service for synchronizing remote files with their local state.
|
||||
*
|
||||
* Serves as a connector to an instance of {@link FileSyncAdapter}, as required by standard Android APIs.
|
||||
*
|
||||
* @author Bartek Przybylski
|
||||
*
|
||||
* @author David A. Velasco
|
||||
*/
|
||||
public class FileSyncService extends Service {
|
||||
|
||||
public static final String SYNC_MESSAGE = "ACCOUNT_SYNC";
|
||||
public static final String SYNC_FOLDER_REMOTE_PATH = "SYNC_FOLDER_REMOTE_PATH";
|
||||
public static final String IN_PROGRESS = "SYNC_IN_PROGRESS";
|
||||
|
@ -48,4 +51,5 @@ public class FileSyncService extends Service {
|
|||
public IBinder onBind(Intent intent) {
|
||||
return new FileSyncAdapter(getApplicationContext(), true).getSyncAdapterBinder();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -862,75 +862,45 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
|
|||
public void onReceive(Context context, Intent intent) {
|
||||
boolean inProgress = intent.getBooleanExtra(FileSyncService.IN_PROGRESS, false);
|
||||
String accountName = intent.getStringExtra(FileSyncService.ACCOUNT_NAME);
|
||||
RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncService.SYNC_RESULT);
|
||||
|
||||
Log_OC.d(TAG, "sync of account " + accountName + " is in_progress: " + inProgress);
|
||||
|
||||
RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncService.SYNC_RESULT);
|
||||
|
||||
if (getAccount() != null && accountName.equals(getAccount().name)) {
|
||||
|
||||
String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH);
|
||||
|
||||
/*
|
||||
boolean fillBlankRoot = false;
|
||||
if (currentDir == null) {
|
||||
currentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
|
||||
fillBlankRoot = (currentDir != null);
|
||||
}
|
||||
*/
|
||||
|
||||
OCFile currentFile = mStorageManager.getFileById(getFile().getFileId());
|
||||
OCFile currentDir = mStorageManager.getFileById(getCurrentDir().getFileId());
|
||||
|
||||
if (currentDir == null) {
|
||||
// current folder was removed from the server
|
||||
Toast.makeText(FileDisplayActivity.this, getString(R.string.sync_current_folder_was_removed), Toast.LENGTH_LONG)
|
||||
.show();
|
||||
onBackPressed();
|
||||
|
||||
} else if (synchFolderRemotePath != null && currentDir.getRemotePath().equals(synchFolderRemotePath)) {
|
||||
|
||||
/*OCFile synchDir = getStorageManager().getFileByPath(synchFolderRemotePath);
|
||||
//boolean needToRefresh = false;
|
||||
if (synchDir == null) {
|
||||
// after synchronizing the current folder does not exist (was deleted in the server) ; need to move to other
|
||||
/*
|
||||
String synchPath = synchFolderRemotePath;
|
||||
do {
|
||||
String synchParentPath = new File(synchPath).getParent();
|
||||
synchParentPath = synchParentPath.endsWith(OCFile.PATH_SEPARATOR) ? synchParentPath : synchParentPath + OCFile.PATH_SEPARATOR;
|
||||
synchDir = getStorageManager().getFileByPath(synchParentPath);
|
||||
popDirname();
|
||||
synchPath = synchParentPath;
|
||||
} while (synchDir == null); // sooner of later will get ROOT, that never is null
|
||||
currentDir = synchDir;
|
||||
*-/
|
||||
Toast.makeText(FileDisplayActivity.this,
|
||||
String.format(getString(R.string.sync_current_folder_was_removed), "LOLO"),
|
||||
Toast.LENGTH_LONG).show();
|
||||
//needToRefresh = true;
|
||||
onBackPressed();
|
||||
} else {*/
|
||||
} else {
|
||||
if (currentFile == null && !getFile().isDirectory()) {
|
||||
// currently selected file was removed in the server, and now we know it
|
||||
cleanSecondFragment();
|
||||
currentFile = currentDir;
|
||||
}
|
||||
|
||||
if (synchFolderRemotePath != null && currentDir.getRemotePath().equals(synchFolderRemotePath)) {
|
||||
OCFileListFragment fileListFragment = getListOfFilesFragment();
|
||||
if (fileListFragment != null) {
|
||||
fileListFragment.listDirectory(currentDir);
|
||||
}
|
||||
//boolean existsSecondFragment = (getSecondFragment() != null);
|
||||
//if (!existsSecondFragment) {
|
||||
if (getSecondFragment() == null) {
|
||||
setFile(currentDir);
|
||||
}
|
||||
//updateFragmentsVisibility(existsSecondFragment);
|
||||
//updateNavigationElementsInActionBar(existsSecondFragment ? getFile() : null);
|
||||
setFile(currentFile);
|
||||
}
|
||||
|
||||
setSupportProgressBarIndeterminateVisibility(inProgress);
|
||||
removeStickyBroadcast(intent);
|
||||
|
||||
mSyncInProgress = inProgress;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (synchResult != null) {
|
||||
if (synchResult.getCode().equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) {
|
||||
mLastSslUntrustedServerResult = synchResult;
|
||||
|
@ -1015,7 +985,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
|
|||
cleanSecondFragment();
|
||||
|
||||
// Sync Folder
|
||||
startSyncFolderOperation(directory.getRemotePath(), directory.getFileId());
|
||||
startSyncFolderOperation(directory);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1425,15 +1395,14 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
|
|||
return null;
|
||||
}
|
||||
|
||||
public void startSyncFolderOperation(String remotePath, long parentId) {
|
||||
public void startSyncFolderOperation(OCFile folder) {
|
||||
long currentSyncTime = System.currentTimeMillis();
|
||||
|
||||
mSyncInProgress = true;
|
||||
|
||||
// perform folder synchronization
|
||||
RemoteOperation synchFolderOp = new SynchronizeFolderOperation( remotePath,
|
||||
RemoteOperation synchFolderOp = new SynchronizeFolderOperation( folder,
|
||||
currentSyncTime,
|
||||
parentId,
|
||||
false,
|
||||
false,
|
||||
getStorageManager(),
|
||||
|
|
|
@ -141,7 +141,7 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName
|
|||
if (mFile != null) {
|
||||
listDirectory(mFile);
|
||||
|
||||
mContainerActivity.startSyncFolderOperation(mFile.getRemotePath(), mFile.getFileId());
|
||||
mContainerActivity.startSyncFolderOperation(mFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName
|
|||
|
||||
public void startImagePreview(OCFile file);
|
||||
|
||||
public void startSyncFolderOperation(String remotePath, long parentId);
|
||||
public void startSyncFolderOperation(OCFile folder);
|
||||
|
||||
/**
|
||||
* Getter for the current DataStorageManager in the container activity
|
||||
|
|
Loading…
Reference in a new issue