Эх сурвалжийг харах

ETag used to detect changes in remote files (not only in folders)

David A. Velasco 9 жил өмнө
parent
commit
5f41bb14d3

+ 2 - 2
src/com/owncloud/android/datamodel/OCFile.java

@@ -498,10 +498,9 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
     }
 
     public void setEtag(String etag) {
-        this.mEtag = etag;
+        this.mEtag = (etag != null ? etag : "");
     }
 
-
     public boolean isShareByLink() {
         return mShareByLink;
     }
@@ -602,4 +601,5 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
         // TODO real implementation
         return false;
     }
+
 }

+ 0 - 1
src/com/owncloud/android/files/FileMenuFilter.java

@@ -34,7 +34,6 @@ import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 

+ 0 - 33
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -230,30 +230,6 @@ public class FileOperationsHelper {
         }
     }
 
-
-    /**
-     * Request the synchronization of a file or the DOWNLOAD OF A FOLDER, including its contents.
-     *
-     * For files, it's the same as syncFile(OCFile file); for folders, this method does not trigger uploads for
-     * file locally modified.
-     *
-     * Kept 'til synchronization of full folders is considered good enough.
-     *
-     * @param file          The file or folder to synchronize
-     */
-    public void downloadFile(OCFile file) {
-        if (!file.isFolder()){
-            syncFile(file);
-
-        } else {
-            Intent intent = new Intent(mFileActivity, OperationsService.class);
-            intent.setAction(OperationsService.ACTION_DOWNLOAD_FOLDER);
-            intent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
-            intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
-            mFileActivity.startService(intent);
-        }
-    }
-
     public void toggleFavorite(OCFile file, boolean isFavorite) {
         file.setFavorite(isFavorite);
         mFileActivity.getStorageManager().saveFile(file);
@@ -327,15 +303,6 @@ public class FileOperationsHelper {
         FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder();
         if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) {
             downloaderBinder.cancel(account, file);
-
-            // TODO - review why is this here, and solve in a better way
-            // Remove etag for parent, if file is a favorite
-            if (file.isFavorite()) {
-                OCFile parent = mFileActivity.getStorageManager().getFileById(file.getParentId());
-                parent.setEtag("");
-                mFileActivity.getStorageManager().saveFile(parent);
-            }
-
         }
         FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
         if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {

+ 1 - 1
src/com/owncloud/android/files/services/FileDownloader.java

@@ -475,7 +475,7 @@ public class FileDownloader extends Service
         file.setNeedsUpdateThumbnail(true);
         file.setModificationTimestamp(mCurrentDownload.getModificationTimestamp());
         file.setModificationTimestampAtLastSyncForData(mCurrentDownload.getModificationTimestamp());
-        // file.setEtag(mCurrentDownload.getEtag());    // TODO Etag, where available
+        file.setEtag(mCurrentDownload.getEtag());
         file.setMimetype(mCurrentDownload.getMimeType());
         file.setStoragePath(mCurrentDownload.getSavePath());
         file.setFileLength((new File(mCurrentDownload.getSavePath()).length()));

+ 3 - 1
src/com/owncloud/android/files/services/FileUploader.java

@@ -688,6 +688,8 @@ public class FileUploader extends Service
         if (result.isSuccess()) {
             updateOCFile(file, (RemoteFile) result.getData().get(0));
             file.setLastSyncDateForProperties(syncDate);
+        } else {
+            Log_OC.e(TAG, "Error reading properties of file after successful upload; this is gonna hurt...");
         }
 
         // / maybe this would be better as part of UploadFileOperation... or
@@ -712,7 +714,7 @@ public class FileUploader extends Service
         file.setMimetype(remoteFile.getMimeType());
         file.setModificationTimestamp(remoteFile.getModifiedTimestamp());
         file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp());
-        // file.setEtag(remoteFile.getEtag());    // TODO Etag, where available
+        file.setEtag(remoteFile.getEtag());
         file.setRemoteId(remoteFile.getRemoteId());
     }
 

+ 6 - 0
src/com/owncloud/android/operations/DownloadFileOperation.java

@@ -52,6 +52,7 @@ public class DownloadFileOperation extends RemoteOperation {
     private OCFile mFile;
     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
     private long mModificationTimestamp = 0;
+    private String mEtag = "";
     private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
     
     private DownloadRemoteFileOperation mDownloadOperation;
@@ -127,6 +128,10 @@ public class DownloadFileOperation extends RemoteOperation {
                 mFile.getModificationTimestamp();
     }
 
+    public String getEtag() {
+        return mEtag;
+    }
+
     @Override
     protected RemoteOperationResult run(OwnCloudClient client) {
         RemoteOperationResult result = null;
@@ -154,6 +159,7 @@ public class DownloadFileOperation extends RemoteOperation {
         
         if (result.isSuccess()) {
             mModificationTimestamp = mDownloadOperation.getModificationTimestamp();
+            mEtag = mDownloadOperation.getEtag();
             newFile = new File(getSavePath());
             newFile.getParentFile().mkdirs();
             moved = tmpFile.renameTo(newFile);

+ 1 - 1
src/com/owncloud/android/operations/DownloadFolderOperation.java

@@ -540,7 +540,7 @@ public class DownloadFolderOperation extends SyncOperation {
 
     private void startSyncFolderOperation(String path){
         Intent intent = new Intent(mContext, OperationsService.class);
-        intent.setAction(OperationsService.ACTION_DOWNLOAD_FOLDER);
+        intent.setAction(OperationsService.ACTION_SYNC_FOLDER);
         intent.putExtra(OperationsService.EXTRA_ACCOUNT, mAccount);
         intent.putExtra(OperationsService.EXTRA_REMOTE_PATH, path);
         mContext.startService(intent);

+ 39 - 145
src/com/owncloud/android/operations/RefreshFolderOperation.java

@@ -20,26 +20,17 @@
 
 package com.owncloud.android.operations;
 
-import java.io.File;
-import java.io.FileInputStream;
-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;
 import java.util.Vector;
 
-import org.apache.http.HttpStatus;
 import android.accounts.Account;
 import android.content.Context;
 import android.content.Intent;
 import android.util.Log;
-//import android.support.v4.content.LocalBroadcastManager;
 
-import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 
@@ -50,7 +41,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation;
-import com.owncloud.android.lib.resources.files.FileUtils;
 import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
 import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
 import com.owncloud.android.lib.resources.files.RemoteFile;
@@ -120,7 +110,10 @@ public class RefreshFolderOperation extends RemoteOperation {
     /** 'True' means that Etag will be ignored */
     private boolean mIgnoreETag;
 
-    
+    private List<SynchronizeFileOperation> mFilesToSyncContents;
+    // this will be used for every file when 'folder synchronization' replaces 'folder download'
+
+
     /**
      * Creates a new instance of {@link RefreshFolderOperation}.
      * 
@@ -154,6 +147,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         mForgottenLocalFiles = new HashMap<String, String>();
         mRemoteFolderChanged = false;
         mIgnoreETag = ignoreETag;
+        mFilesToSyncContents = new Vector<SynchronizeFileOperation>();
     }
     
     
@@ -191,7 +185,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         mConflictsFound = 0;
         mForgottenLocalFiles.clear();
         
-        if (FileUtils.PATH_SEPARATOR.equals(mLocalFolder.getRemotePath()) && !mSyncFullAccount) {
+        if (OCFile.ROOT_PATH.equals(mLocalFolder.getRemotePath()) && !mSyncFullAccount) {
             updateOCVersion(client);
         }
         
@@ -201,9 +195,14 @@ public class RefreshFolderOperation extends RemoteOperation {
             if (mRemoteFolderChanged) {
                 result = fetchAndSyncRemoteFolder(client);
             } else {
-                // TODO Enable when "On Device" is recovered ?
+                fetchFavoritesToSyncFromLocalData();
                 mChildren = mStorageManager.getFolderContent(mLocalFolder/*, false*/);
             }
+
+            if (result.isSuccess()) {
+                // request for the synchronization of KEPT-IN-SYNC file contents
+                startContentSynchronizations(mFilesToSyncContents, client);
+            }
         }
         
         if (!mSyncFullAccount) {            
@@ -239,9 +238,8 @@ public class RefreshFolderOperation extends RemoteOperation {
     private RemoteOperationResult checkForChanges(OwnCloudClient client) {
         mRemoteFolderChanged = true;
         RemoteOperationResult result = null;
-        String remotePath = null;
+        String remotePath = mLocalFolder.getRemotePath();
 
-        remotePath = mLocalFolder.getRemotePath();
         Log_OC.d(TAG, "Checking changes in " + mAccount.name + remotePath);
         
         // remote request 
@@ -264,7 +262,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
             result = new RemoteOperationResult(ResultCode.OK);
         
-            Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " + 
+            Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " +
                     (mRemoteFolderChanged ? "changed" : "not changed"));
             
         } else {
@@ -337,15 +335,15 @@ public class RefreshFolderOperation extends RemoteOperation {
         mLocalFolder = mStorageManager.getFileByPath(mLocalFolder.getRemotePath());
 
         // parse data from remote folder 
-        OCFile remoteFolder = fillOCFile((RemoteFile)folderAndFiles.get(0));
+        OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(0));
         remoteFolder.setParentId(mLocalFolder.getParentId());
         remoteFolder.setFileId(mLocalFolder.getFileId());
         
-        Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath() 
+        Log_OC.d(TAG, "Remote folder " + mLocalFolder.getRemotePath()
                 + " changed - starting update of local data ");
         
         List<OCFile> updatedFiles = new Vector<OCFile>(folderAndFiles.size() - 1);
-        List<SynchronizeFileOperation> filesToSyncContents = new Vector<SynchronizeFileOperation>();
+        mFilesToSyncContents.clear();
 
         // get current data about local contents of the folder to synchronize
         // TODO Enable when "On Device" is recovered ?
@@ -359,7 +357,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         OCFile remoteFile = null, localFile = null;
         for (int i=1; i<folderAndFiles.size(); i++) {
             /// new OCFile instance with the data from the server
-            remoteFile = fillOCFile((RemoteFile)folderAndFiles.get(i));
+            remoteFile = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(i));
             remoteFile.setParentId(mLocalFolder.getFileId());
 
             /// retrieve local data for the read file 
@@ -377,9 +375,8 @@ public class RefreshFolderOperation extends RemoteOperation {
                         localFile.getModificationTimestampAtLastSyncForData()
                 );
                 remoteFile.setStoragePath(localFile.getStoragePath());
-                // eTag will not be updated unless contents are synchronized 
-                //  (Synchronize[File|Folder]Operation with remoteFile as parameter)
-                remoteFile.setEtag(localFile.getEtag());    
+                // eTag will not be updated unless file CONTENTS are synchronized
+                remoteFile.setEtag(localFile.getEtag());
                 if (remoteFile.isFolder()) {
                     remoteFile.setFileLength(localFile.getFileLength()); 
                         // TODO move operations about size of folders to FileContentProvider
@@ -392,15 +389,12 @@ public class RefreshFolderOperation extends RemoteOperation {
                 remoteFile.setPublicLink(localFile.getPublicLink());
                 remoteFile.setShareByLink(localFile.isShareByLink());
             } else {
-                // remote eTag will not be updated unless contents are synchronized 
-                //  (Synchronize[File|Folder]Operation with remoteFile as parameter)
-                remoteFile.setEtag(""); 
+                // remote eTag will not be updated unless file CONTENTS are synchronized
+                remoteFile.setEtag("");
             }
 
             /// check and fix, if needed, local storage path
-            checkAndFixForeignStoragePath(remoteFile);      // policy - local files are COPIED 
-                                                            // into the ownCloud local folder;
-            searchForLocalFileInDefaultPath(remoteFile);    // legacy   
+            FileStorageUtils.searchForLocalFileInDefaultPath(remoteFile, mAccount);
 
             /// prepare content synchronization for kept-in-sync files
             if (remoteFile.isFavorite()) {
@@ -411,18 +405,15 @@ public class RefreshFolderOperation extends RemoteOperation {
                                                                                     mContext
                                                                                     );
                 
-                filesToSyncContents.add(operation);
+                mFilesToSyncContents.add(operation);
             }
-            
+
             updatedFiles.add(remoteFile);
         }
 
         // save updated contents in local database
         mStorageManager.saveFolder(remoteFolder, updatedFiles, localFilesMap.values());
 
-        // request for the synchronization of file contents AFTER saving current remote properties
-        startContentSynchronizations(filesToSyncContents, client);
-
         mChildren = updatedFiles;
     }
 
@@ -460,97 +451,6 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
 
-    public boolean isMultiStatus(int status) {
-        return (status == HttpStatus.SC_MULTI_STATUS); 
-    }
-
-    /**
-     * Creates and populates a new {@link OCFile} object with the data read from the server.
-     * 
-     * @param remote    remote file read from the server (remote file or folder).
-     * @return          New OCFile instance representing the remote resource described by we.
-     */
-    private OCFile fillOCFile(RemoteFile remote) {
-        OCFile file = new OCFile(remote.getRemotePath());
-        file.setCreationTimestamp(remote.getCreationTimestamp());
-        file.setFileLength(remote.getLength());
-        file.setMimetype(remote.getMimeType());
-        file.setModificationTimestamp(remote.getModifiedTimestamp());
-        file.setEtag(remote.getEtag());
-        file.setPermissions(remote.getPermissions());
-        file.setRemoteId(remote.getRemoteId());
-        return file;
-    }
-    
-
-    /**
-     * Checks the storage path of the OCFile received as parameter. 
-     * If it's out of the local ownCloud folder, tries to copy the file inside it. 
-     * 
-     * If the copy fails, the link to the local file is nullified. The account of forgotten 
-     * files is kept in {@link #mForgottenLocalFiles}
-     *) 
-     * @param file      File to check and fix.
-     */
-    private void checkAndFixForeignStoragePath(OCFile file) {
-        String storagePath = file.getStoragePath();
-        String expectedPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file);
-        if (storagePath != null && !storagePath.equals(expectedPath)) {
-            /// fix storagePaths out of the local ownCloud folder
-            File originalFile = new File(storagePath);
-            if (FileStorageUtils.getUsableSpace(mAccount.name) < originalFile.length()) {
-                mForgottenLocalFiles.put(file.getRemotePath(), storagePath);
-                file.setStoragePath(null);
-                    
-            } else {
-                InputStream in = null;
-                OutputStream out = null;
-                try {
-                    File expectedFile = new File(expectedPath);
-                    File expectedParent = expectedFile.getParentFile();
-                    expectedParent.mkdirs();
-                    if (!expectedParent.isDirectory()) {
-                        throw new IOException(
-                                "Unexpected error: parent directory could not be created"
-                        );
-                    }
-                    expectedFile.createNewFile();
-                    if (!expectedFile.isFile()) {
-                        throw new IOException("Unexpected error: target file could not be created");
-                    }                    
-                    in = new FileInputStream(originalFile);
-                    out = new FileOutputStream(expectedFile);
-                    byte[] buf = new byte[1024];
-                    int len;
-                    while ((len = in.read(buf)) > 0){
-                        out.write(buf, 0, len);
-                    }
-                    file.setStoragePath(expectedPath);
-                    
-                } catch (Exception e) {
-                    Log_OC.e(TAG, "Exception while copying foreign file " + expectedPath, e);
-                    mForgottenLocalFiles.put(file.getRemotePath(), storagePath);
-                    file.setStoragePath(null);
-                    
-                } finally {
-                    try {
-                        if (in != null) in.close();
-                    } catch (Exception e) {
-                        Log_OC.d(TAG, "Weird exception while closing input stream for " 
-                                + storagePath + " (ignoring)", e);
-                    }
-                    try {
-                        if (out != null) out.close();
-                    } catch (Exception e) {
-                        Log_OC.d(TAG, "Weird exception while closing output stream for " 
-                                + expectedPath + " (ignoring)", e);
-                    }
-                }
-            }
-        }
-    }
-    
-    
     private RemoteOperationResult refreshSharesForFolder(OwnCloudClient client) {
         RemoteOperationResult result = null;
         
@@ -572,24 +472,6 @@ public class RefreshFolderOperation 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.isFolder()) {
-            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.
@@ -614,8 +496,20 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
 
-    public boolean getRemoteFolderChanged() {
-        return mRemoteFolderChanged;
+    private void fetchFavoritesToSyncFromLocalData() {
+        List<OCFile> children = mStorageManager.getFolderContent(mLocalFolder);
+        for (OCFile child : children) {
+            if (!child.isFolder() && child.isFavorite()) {
+                SynchronizeFileOperation operation = new SynchronizeFileOperation(
+                        child,
+                        child,  // cheating with the remote file to get an update to server; to refactor
+                        mAccount,
+                        true,
+                        mContext
+                );
+                mFilesToSyncContents.add(operation);
+            }
+        }
     }
 
 }

+ 7 - 10
src/com/owncloud/android/operations/SynchronizeFileOperation.java

@@ -22,7 +22,6 @@
 
 package com.owncloud.android.operations;
 
-import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileUploader;
@@ -208,15 +207,13 @@ public class SynchronizeFileOperation extends SyncOperation {
 
                 /// check changes in server and local file
                 boolean serverChanged = false;
-                /* time for eTag is coming, but not yet
-                    if (mServerFile.getEtag() != null) {
-                        serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag()));
-                    } else { */
-                serverChanged = (
-                    mServerFile.getModificationTimestamp() !=
-                            mLocalFile.getModificationTimestampAtLastSyncForData()
-                );
-                //}
+                if (mLocalFile.getEtag() == null || mLocalFile.getEtag().length() == 0) {
+                    // file uploaded (null) or downloaded ("") before upgrade to version 1.8.0; check the old condition
+                    serverChanged = mServerFile.getModificationTimestamp() !=
+                            mLocalFile.getModificationTimestampAtLastSyncForData();
+                } else {
+                    serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag()));
+                }
                 boolean localChanged = (
                     mLocalFile.getLocalModificationTimestamp() > mLocalFile.getLastSyncDateForData()
                 );

+ 4 - 38
src/com/owncloud/android/operations/SynchronizeFolderOperation.java

@@ -278,7 +278,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
         FileDataStorageManager storageManager = getStorageManager();
         
         // parse data from remote folder
-        OCFile remoteFolder = fillOCFile((RemoteFile)folderAndFiles.get(0));
+        OCFile remoteFolder = FileStorageUtils.fillOCFile((RemoteFile) folderAndFiles.get(0));
         remoteFolder.setParentId(mLocalFolder.getParentId());
         remoteFolder.setFileId(mLocalFolder.getFileId());
 
@@ -305,7 +305,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
         OCFile remoteFile = null, localFile = null;
         for (int i=1; i<folderAndFiles.size(); i++) {
             /// new OCFile instance with the data from the server
-            remoteFile = fillOCFile((RemoteFile)folderAndFiles.get(i));
+            remoteFile = FileStorageUtils.fillOCFile((RemoteFile)folderAndFiles.get(i));
             remoteFile.setParentId(mLocalFolder.getFileId());
 
             /// retrieve local data for the read file
@@ -324,7 +324,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
                 );
                 remoteFile.setStoragePath(localFile.getStoragePath());
                 // eTag will not be updated unless contents are synchronized
-                //  (Synchronize[File|Folder]Operation with remoteFile as parameter)
                 remoteFile.setEtag(localFile.getEtag());
                 if (remoteFile.isFolder()) {
                     remoteFile.setFileLength(localFile.getFileLength());
@@ -339,7 +338,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
                 remoteFile.setShareByLink(localFile.isShareByLink());
             } else {
                 // remote eTag will not be updated unless contents are synchronized
-                //  (Synchronize[File|Folder]Operation with remoteFile as parameter)
                 remoteFile.setEtag("");
             }
 
@@ -356,9 +354,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
                     startSyncFolderOperation(remoteFile.getRemotePath());
                 }
 
-            //} else if (remoteFile.isFavorite()) {
             } else {
-                /// prepare content synchronization for kept-in-sync files
+                /// prepare content synchronization for files (any file, not just favorites)
                 SynchronizeFileOperation operation = new SynchronizeFileOperation(
                         localFile,
                         remoteFile,
@@ -368,17 +365,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
                     );
                 mFilesToSyncContents.add(operation);
                 
-            /*} else {
-                /// prepare limited synchronization for regular files
-                SynchronizeFileOperation operation = new SynchronizeFileOperation(
-                        localFile,
-                        remoteFile,
-                        mAccount,
-                        true,
-                        false,
-                        mContext
-                    );
-                mFilesToSyncContentsWithoutUpload.add(operation);*/
             }
 
             updatedFiles.add(remoteFile);
@@ -405,7 +391,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
                 }
 
             } else {
-                /// prepare limited synchronization for regular files
+                /// synchronization for regular files
                 if (!child.isDown()) {
                     mFilesForDirectDownload.add(child);
 
@@ -487,26 +473,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
     }
 
     
-    /**
-     * Creates and populates a new {@link com.owncloud.android.datamodel.OCFile}
-     * object with the data read from the server.
-     *
-     * @param remote    remote file read from the server (remote file or folder).
-     * @return          New OCFile instance representing the remote resource described by we.
-     */
-    private OCFile fillOCFile(RemoteFile remote) {
-        OCFile file = new OCFile(remote.getRemotePath());
-        file.setCreationTimestamp(remote.getCreationTimestamp());
-        file.setFileLength(remote.getLength());
-        file.setMimetype(remote.getMimeType());
-        file.setModificationTimestamp(remote.getModifiedTimestamp());
-        file.setEtag(remote.getEtag());
-        file.setPermissions(remote.getPermissions());
-        file.setRemoteId(remote.getRemoteId());
-        return file;
-    }
-
-
     /**
      * Scans the default location for saving local copies of files searching for
      * a 'lost' file with the same full name as the {@link com.owncloud.android.datamodel.OCFile}

+ 1 - 1
src/com/owncloud/android/operations/UploadFileOperation.java

@@ -403,7 +403,7 @@ public class UploadFileOperation extends RemoteOperation {
         newFile.setModificationTimestamp(mFile.getModificationTimestamp());
         newFile.setModificationTimestampAtLastSyncForData(
                 mFile.getModificationTimestampAtLastSyncForData());
-        // newFile.setEtag(mFile.getEtag())
+        newFile.setEtag(mFile.getEtag());
         newFile.setFavorite(mFile.isFavorite());
         newFile.setLastSyncDateForProperties(mFile.getLastSyncDateForProperties());
         newFile.setLastSyncDateForData(mFile.getLastSyncDateForData());

+ 0 - 12
src/com/owncloud/android/services/OperationsService.java

@@ -53,7 +53,6 @@ import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation;
 import com.owncloud.android.operations.CopyFileOperation;
-import com.owncloud.android.operations.DownloadFolderOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.CreateShareOperation;
 import com.owncloud.android.operations.GetServerInfoOperation;
@@ -102,7 +101,6 @@ public class OperationsService extends Service {
     public static final String ACTION_CREATE_FOLDER = "CREATE_FOLDER";
     public static final String ACTION_SYNC_FILE = "SYNC_FILE";
     public static final String ACTION_SYNC_FOLDER = "SYNC_FOLDER";
-    public static final String ACTION_DOWNLOAD_FOLDER = "DOWNLOAD_FOLDER" ;
     public static final String ACTION_MOVE_FILE = "MOVE_FILE";
     public static final String ACTION_COPY_FILE = "COPY_FILE";
 
@@ -626,16 +624,6 @@ public class OperationsService extends Service {
                             System.currentTimeMillis()  // TODO remove this dependency from construction time
                     );
 
-                } else if (action.equals(ACTION_DOWNLOAD_FOLDER)) { // TODO remove when sync of folders is good enough
-                    // Download folder (all its descendant files are downloaded)
-                    String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    operation = new DownloadFolderOperation(
-                            this,
-                            remotePath,
-                            account,
-                            System.currentTimeMillis()
-                    );
-
                 } else if (action.equals(ACTION_MOVE_FILE)) {
                     // Move file/folder
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);

+ 9 - 28
src/com/owncloud/android/syncadapter/FileSyncAdapter.java

@@ -30,7 +30,6 @@ import java.util.Map;
 
 import org.apache.jackrabbit.webdav.DavException;
 
-import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -59,7 +58,7 @@ import android.support.v4.app.NotificationCompat;
  * Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing 
  * ownCloud files.
  * 
- * Performs a full synchronization of the account recieved in {@link #onPerformSync(Account, Bundle,
+ * Performs a full synchronization of the account received in {@link #onPerformSync(Account, Bundle,
  * String, ContentProviderClient, SyncResult)}.
  */
 public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
@@ -77,9 +76,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             ".EVENT_FULL_SYNC_END";
     public static final String EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED =
             FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED";
-    //public static final String EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED =
-    // FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED";
-    
+
     public static final String EXTRA_ACCOUNT_NAME = FileSyncAdapter.class.getName() +
             ".EXTRA_ACCOUNT_NAME";
     public static final String EXTRA_FOLDER_PATH = FileSyncAdapter.class.getName() +
@@ -268,16 +265,6 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
         if (mFailedResultsCounter > MAX_FAILED_RESULTS || isFinisher(mLastFailedResult))
             return;
         
-        /*
-        OCFile folder, 
-        long currentSyncTime, 
-        boolean updateFolderProperties,
-        boolean syncFullAccount,
-        DataStorageManager dataStorageManager, 
-        Account account, 
-        Context context ) {
-        }
-        */
         // folder synchronization
         RefreshFolderOperation synchFolderOp = new RefreshFolderOperation( folder,
                                                                                    mCurrentSyncTime,
@@ -308,7 +295,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                 // synchronize children folders 
                 List<OCFile> children = synchFolderOp.getChildren();
                 // beware of the 'hidden' recursion here!
-                fetchChildren(folder, children, synchFolderOp.getRemoteFolderChanged());
+                syncChildren(children);
             }
             
         } else {
@@ -351,25 +338,19 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
 
     /**
      * Triggers the synchronization of any folder contained in the list of received files.
+     *
+     * No consideration of etag here because it MUST walk down anyway, in case that kept-in-sync files
+     * have local changes.
      * 
      * @param files         Files to recursively synchronize.
      */
-    private void fetchChildren(OCFile parent, List<OCFile> files, boolean parentEtagChanged) {
+    private void syncChildren(List<OCFile> files) {
         int i;
-        OCFile newFile = null;
-        //String etag = null;
-        //boolean syncDown = false;
+        OCFile newFile;
         for (i=0; i < files.size() && !mCancellation; i++) {
             newFile = files.get(i);
             if (newFile.isFolder()) {
-                /*
-                etag = newFile.getEtag();
-                syncDown = (parentEtagChanged || etag == null || etag.length() == 0);
-                if(syncDown) { */
-                    synchronizeFolder(newFile);
-                    //sendLocalBroadcast(EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED, parent.getRemotePath(),
-                    // null);
-                //}
+                synchronizeFolder(newFile);
             }
         }
        

+ 0 - 29
src/com/owncloud/android/ui/dialog/RemoveFileDialogFragment.java

@@ -25,7 +25,6 @@ package com.owncloud.android.ui.dialog;
  * 
  *  Triggers the removal according to the user response.
  */
-import java.util.Vector;
 
 import android.app.Dialog;
 import android.os.Bundle;
@@ -106,34 +105,6 @@ implements ConfirmationDialogFragmentListener {
     public void onCancel(String callerTag) {
         ComponentsGetter cg = (ComponentsGetter)getActivity();
         cg.getFileOperationsHelper().removeFile(mTargetFile, true);
-        
-        FileDataStorageManager storageManager = cg.getStorageManager();
-        
-        boolean containsFavorite = false;
-        if (mTargetFile.isFolder()) {
-            // TODO Enable when "On Device" is recovered ?
-            Vector<OCFile> files = storageManager.getFolderContent(mTargetFile/*, false*/);
-            for(OCFile file: files) {
-                containsFavorite = file.isFavorite() || containsFavorite;
-
-                if (containsFavorite)
-                    break;
-            }
-        }
-
-        // Remove etag for parent, if file is a favorite
-        // or is a folder and contains favorite
-        if (mTargetFile.isFavorite() || containsFavorite) {
-            OCFile folder = null;
-            if (mTargetFile.isFolder()) {
-                folder = mTargetFile;
-            } else {
-                folder = storageManager.getFileById(mTargetFile.getParentId());
-            }
-            
-           folder.setEtag("");
-           storageManager.saveFile(folder);
-        }
     }
 
     @Override

+ 1 - 4
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -363,10 +363,7 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
                 dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
                 return true;
             }
-            case R.id.action_download_file: {
-                mContainerActivity.getFileOperationsHelper().downloadFile(mTargetFile);
-                return true;
-            }
+            case R.id.action_download_file:
             case R.id.action_sync_file: {
                 mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
                 return true;

+ 31 - 2
src/com/owncloud/android/utils/FileStorageUtils.java

@@ -32,6 +32,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.resources.files.RemoteFile;
 
+import android.accounts.Account;
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -120,7 +121,7 @@ public class FileStorageUtils {
      * Creates and populates a new {@link OCFile} object with the data read from the server.
      * 
      * @param remote    remote file read from the server (remote file or folder).
-     * @return          New OCFile instance representing the remote resource described by we.
+     * @return          New OCFile instance representing the remote resource described by remote.
      */
     public static OCFile fillOCFile(RemoteFile remote) {
         OCFile file = new OCFile(remote.getRemotePath());
@@ -302,5 +303,33 @@ public class FileStorageUtils {
         String result = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
         return (result != null) ? result : "";
     }
-  
+
+    /**
+     * 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.
+     *
+     * This method helps to keep linked local copies of the files when the app is uninstalled, and then
+     * reinstalled in the device. OR after the cache of the app was deleted in system settings.
+     *
+     * The method is assuming that all the local changes in the file where synchronized in the past. This is dangerous,
+     * but assuming the contrary could lead to massive unnecessary synchronizations of downloaded file after deleting
+     * the app cache.
+     *
+     * This should be changed in the near future to avoid any chance of data loss, but we need to add some options
+     * to limit hard automatic synchronizations to wifi, unless the user wants otherwise.
+     *
+     * @param file      File to associate a possible 'lost' local file.
+     * @param account   Account holding file.
+     */
+    public static void searchForLocalFileInDefaultPath(OCFile file, Account account) {
+        if (file.getStoragePath() == null && !file.isFolder()) {
+            File f = new File(FileStorageUtils.getDefaultSavePathFor(account.name, file));
+            if (f.exists()) {
+                file.setStoragePath(f.getAbsolutePath());
+                file.setLastSyncDateForData(f.lastModified());
+            }
+        }
+    }
+
 }