Ver Fonte

Join cancelation of downloads and uploads in 'cancel sync', both for files and folders

David A. Velasco há 9 anos atrás
pai
commit
9b5506f81e

+ 5 - 0
res/menu/file_actions_menu.xml

@@ -43,6 +43,11 @@
         android:title="@string/filedetails_sync_file"
         android:icon="@drawable/ic_action_refresh"
         android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_cancel_sync"
+        android:title="@string/common_cancel_sync"
+        android:icon="@android:drawable/ic_menu_close_clear_cancel"
+        android:orderInCategory="1" />
     <item
         android:id="@+id/action_cancel_download"
         android:title="@string/common_cancel_download"

+ 1 - 2
res/values/strings.xml

@@ -89,8 +89,7 @@
     <string name="common_yes">Yes</string>
     <string name="common_no">No</string>
     <string name="common_ok">OK</string>
-    <string name="common_cancel_download">Cancel download</string>
-    <string name="common_cancel_upload">Cancel upload</string>
+    <string name="common_cancel_sync">Cancel synchronization</string>
     <string name="common_cancel">Cancel</string>
     <string name="common_save_exit">Save &amp; Exit</string>
     <string name="common_error">Error</string>

+ 33 - 22
src/com/owncloud/android/files/FileMenuFilter.java

@@ -106,6 +106,22 @@ public class FileMenuFilter {
      * @param toHide            List to save the options that must be shown in the menu.
      */
     private void filter(List<Integer> toShow, List <Integer> toHide) {
+        boolean synchronizing = false;
+        if (mComponentsGetter != null && mFile != null && mAccount != null) {
+            OperationsServiceBinder opsBinder = mComponentsGetter.getOperationsServiceBinder();
+            FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
+            FileDownloaderBinder downloaderBinder = mComponentsGetter.getFileDownloaderBinder();
+            synchronizing = (
+                // comparing local and remote
+                (opsBinder != null && opsBinder.isSynchronizing(mAccount, mFile.getRemotePath())) ||
+                // downloading
+                (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, mFile)) ||
+                // uploading
+                (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile))
+            );
+        }
+
+        /*
         boolean downloading = false;
         boolean uploading = false;
         if (mComponentsGetter != null && mFile != null && mAccount != null) {
@@ -116,11 +132,12 @@ public class FileMenuFilter {
             FileUploaderBinder uploaderBinder = mComponentsGetter.getFileUploaderBinder();
             uploading = (uploaderBinder != null && uploaderBinder.isUploading(mAccount, mFile));
         }
-
+        */
+        
         /// decision is taken for each possible action on a file in the menu
 
         // DOWNLOAD 
-        if (mFile == null || mFile.isDown() || downloading || uploading) {
+        if (mFile == null || mFile.isDown() || synchronizing) {
             toHide.add(R.id.action_download_file);
 
         } else {
@@ -128,7 +145,7 @@ public class FileMenuFilter {
         }
 
         // RENAME
-        if (mFile == null || downloading || uploading) {
+        if (mFile == null || synchronizing) {
             toHide.add(R.id.action_rename_file);
 
         } else {
@@ -136,7 +153,7 @@ public class FileMenuFilter {
         }
 
         // MOVE & COPY
-        if (mFile == null || downloading || uploading) {
+        if (mFile == null || synchronizing) {
             toHide.add(R.id.action_move);
             toHide.add(R.id.action_copy);
         } else {
@@ -145,7 +162,7 @@ public class FileMenuFilter {
         }
 
         // REMOVE
-        if (mFile == null || downloading || uploading) {
+        if (mFile == null || synchronizing) {
             toHide.add(R.id.action_remove_file);
 
         } else {
@@ -153,31 +170,25 @@ public class FileMenuFilter {
         }
 
         // OPEN WITH (different to preview!)
-        if (mFile == null || mFile.isFolder() || !mFile.isDown() || downloading || uploading) {
+        if (mFile == null || mFile.isFolder() || !mFile.isDown() || synchronizing) {
             toHide.add(R.id.action_open_file_with);
 
         } else {
             toShow.add(R.id.action_open_file_with);
         }
 
+        // CANCEL SYNCHRONIZATION
+        if (mFile == null || !synchronizing) {
+            toHide.add(R.id.action_cancel_sync);
 
-        // CANCEL DOWNLOAD
-        if (mFile == null || !downloading) {
-            toHide.add(R.id.action_cancel_download);
         } else {
-            toShow.add(R.id.action_cancel_download);
+            toShow.add(R.id.action_cancel_sync);
         }
 
-        // CANCEL UPLOAD
-        if (mFile == null || !uploading || mFile.isFolder()) {
-            toHide.add(R.id.action_cancel_upload);
-        } else {
-            toShow.add(R.id.action_cancel_upload);
-        }
-
-        // SYNC FILE CONTENTS
-        if (mFile == null || (!mFile.isFolder() && !mFile.isDown()) || downloading || uploading) {
+        // SYNC CONTENTS (BOTH FILE AND FOLDER)
+        if (mFile == null || (!mFile.isFolder() && !mFile.isDown()) || synchronizing) {
             toHide.add(R.id.action_sync_file);
+
         } else {
             toShow.add(R.id.action_sync_file);
         }
@@ -210,21 +221,21 @@ public class FileMenuFilter {
         // SEND
         boolean sendAllowed = (mContext != null &&
                 mContext.getString(R.string.send_files_to_other_apps).equalsIgnoreCase("on"));
-        if (mFile == null || !sendAllowed || mFile.isFolder() || uploading || downloading) {
+        if (mFile == null || !sendAllowed || mFile.isFolder() || synchronizing) {
             toHide.add(R.id.action_send_file);
         } else {
             toShow.add(R.id.action_send_file);
         }
 
         // FAVORITES
-        if (mFile == null || downloading || uploading || mFile.isFolder() || mFile.isFavorite()) {
+        if (mFile == null || synchronizing || mFile.isFolder() || mFile.isFavorite()) {
             toHide.add(R.id.action_favorite_file);
         } else {
             toShow.add(R.id.action_favorite_file);
         }
 
         // UNFAVORITES
-        if (mFile == null || downloading || uploading || mFile.isFolder() || !mFile.isFavorite()) {
+        if (mFile == null || synchronizing || mFile.isFolder() || !mFile.isFavorite()) {
             toHide.add(R.id.action_unfavorite_file);
         } else {
             toShow.add(R.id.action_unfavorite_file);

+ 3 - 2
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -325,7 +325,6 @@ public class FileOperationsHelper {
 
         // for both files and folders
         FileDownloaderBinder downloaderBinder = mFileActivity.getFileDownloaderBinder();
-        FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
         if (downloaderBinder != null && downloaderBinder.isDownloading(account, file)) {
             downloaderBinder.cancel(account, file);
 
@@ -337,7 +336,9 @@ public class FileOperationsHelper {
                 mFileActivity.getStorageManager().saveFile(parent);
             }
 
-        } else if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {
+        }
+        FileUploaderBinder uploaderBinder = mFileActivity.getFileUploaderBinder();
+        if (uploaderBinder != null && uploaderBinder.isUploading(account, file)) {
             uploaderBinder.cancel(account, file);
         }
     }

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

@@ -153,7 +153,7 @@ public class FileDownloader extends Service
 
     /**
      * Entry point to add one or several files to the queue of downloads.
-     * <p/>
+     *
      * 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.
      */
@@ -169,12 +169,6 @@ public class FileDownloader extends Service
         } else {
             final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
             final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
-
-            /*Log_OC.v(
-                    "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                    "Received request to download file"
-            );*/
-
             AbstractList<String> requestedDownloads = new Vector<String>();
             try {
                 DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
@@ -185,10 +179,6 @@ public class FileDownloader extends Service
                 );
                 String downloadKey = putResult.first;
                 requestedDownloads.add(downloadKey);
-                    /*Log_OC.v(
-                        "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                        "Download on " + file.getRemotePath() + " added to queue"
-                    );*/
 
                 // Store file on db with state 'downloading'
                     /*
@@ -275,34 +265,23 @@ public class FileDownloader extends Service
          * @param file    A file in the queue of pending downloads
          */
         public void cancel(Account account, OCFile file) {
-            /*Log_OC.v(
-                    "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                    "Received request to cancel download of " + file.getRemotePath()
-            );
-            Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                    "Removing download of " + file.getRemotePath());*/
-            Pair<DownloadFileOperation, String> removeResult =
-                    mPendingDownloads.remove(account, file.getRemotePath());
+            Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.remove(account, file.getRemotePath());
             DownloadFileOperation download = removeResult.first;
             if (download != null) {
-                /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                        "Canceling returned download of " + file.getRemotePath());*/
                 download.cancel();
             } else {
                 if (mCurrentDownload != null && mCurrentAccount != null &&
                         mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
                         account.name.equals(mCurrentAccount.name)) {
-                    /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                     "Canceling current sync as descendant: " + mCurrentDownload.getRemotePath());*/
                     mCurrentDownload.cancel();
                 }
             }
         }
 
         /**
-         * Cancels a pending or current upload for an account
+         * Cancels all the downloads for an account
          *
-         * @param account Owncloud accountName where the remote file will be stored.
+         * @param account   ownCloud account.
          */
         public void cancel(Account account) {
             Log_OC.d(TAG, "Account= " + account.name);
@@ -349,7 +328,6 @@ public class FileDownloader extends Service
                 OnDatatransferProgressListener listener, Account account, OCFile file
         ) {
             if (account == null || file == null || listener == null) return;
-            //String targetKey = buildKey(account, file.getRemotePath());
             mBoundListeners.put(file.getFileId(), listener);
         }
 
@@ -357,15 +335,14 @@ public class FileDownloader extends Service
         /**
          * Removes a listener interested in the progress of the download for a concrete file.
          *
-         * @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 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.
          */
         public void removeDatatransferProgressListener(
                 OnDatatransferProgressListener listener, Account account, OCFile file
         ) {
             if (account == null || file == null || listener == null) return;
-            //String targetKey = buildKey(account, file.getRemotePath());
             Long fileId = file.getFileId();
             if (mBoundListeners.get(fileId) == listener) {
                 mBoundListeners.remove(fileId);
@@ -375,8 +352,6 @@ public class FileDownloader extends Service
         @Override
         public void onTransferProgress(long progressRate, long totalTransferredSoFar,
                                        long totalToTransfer, String fileName) {
-            //String key = buildKey(mCurrentDownload.getAccount(),
-            // mCurrentDownload.getFile().getRemotePath());
             OnDatatransferProgressListener boundListener =
                     mBoundListeners.get(mCurrentDownload.getFile().getFileId());
             if (boundListener != null) {
@@ -385,23 +360,12 @@ public class FileDownloader extends Service
             }
         }
 
-        /**
-         * Review downloads and cancel it if its account doesn't exist
-         */
-        public void checkAccountOfCurrentDownload() {
-            if (mCurrentDownload != null &&
-                    !AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) {
-                mCurrentDownload.cancel();
-            }
-            // The rest of downloads are cancelled when they try to start
-        }
-
     }
 
 
     /**
      * Download worker. Performs the pending downloads in the order they were requested.
-     * <p/>
+
      * Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}.
      */
     private static class ServiceHandler extends Handler {

+ 38 - 58
src/com/owncloud/android/files/services/FileUploader.java

@@ -113,7 +113,7 @@ public class FileUploader extends Service
     private ServiceHandler mServiceHandler;
     private IBinder mBinder;
     private OwnCloudClient mUploadClient = null;
-    private Account mLastAccount = null;
+    private Account mCurrentAccount = null;
     private FileDataStorageManager mStorageManager;
 
     private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<UploadFileOperation>();
@@ -131,20 +131,6 @@ public class FileUploader extends Service
         return FileUploader.class.getName() + UPLOAD_FINISH_MESSAGE;
     }
 
-    /**
-     * Builds a key for mPendingUploads from the account and file to upload
-     *
-     * @param account   Account where the file to upload is stored
-     * @param file      File to upload
-     */
-    private String buildRemoteName(Account account, OCFile file) {
-        return account.name + file.getRemotePath();
-    }
-
-    private String buildRemoteName(Account account, String remotePath) {
-        return account.name + remotePath;
-    }
-
     /**
      * Checks if an ownCloud server version should support chunked uploads.
      *
@@ -152,6 +138,8 @@ public class FileUploader extends Service
      *            server.
      * @return 'True' if the ownCloud server with version supports chunked
      *         uploads.
+     *
+     * TODO - move to OCClient
      */
     private static boolean chunkedUploadIsSupported(OwnCloudVersion version) {
         return (version != null && version.compareTo(OwnCloudVersion.owncloud_v4_5) >= 0);
@@ -281,7 +269,7 @@ public class FileUploader extends Service
             files = new OCFile[localPaths.length];
             for (int i = 0; i < localPaths.length; i++) {
                 files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i],
-                        ((mimeTypes != null) ? mimeTypes[i] : null), storageManager);
+                        ((mimeTypes != null) ? mimeTypes[i] : null));
                 if (files[i] == null) {
                     // TODO @andomaex add failure Notification
                     return Service.START_NOT_STICKY;
@@ -389,24 +377,27 @@ public class FileUploader extends Service
         /**
          * Cancels a pending or current upload of a remote file.
          *
-         * @param account Owncloud account where the remote file will be stored.
-         * @param file A file in the queue of pending uploads
+         * @param account   ownCloud account where the remote file will be stored.
+         * @param file      A file in the queue of pending uploads
          */
         public void cancel(Account account, OCFile file) {
-            UploadFileOperation upload;
-            //synchronized (mPendingUploads) {
-                Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
-                upload = removeResult.first;
-            //}
+            Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
+            UploadFileOperation upload = removeResult.first;
             if (upload != null) {
                 upload.cancel();
+            } else {
+                if (mCurrentUpload != null && mCurrentAccount != null &&
+                        mCurrentUpload.getRemotePath().startsWith(file.getRemotePath()) &&
+                        account.name.equals(mCurrentAccount.name)) {
+                    mCurrentUpload.cancel();
+                }
             }
         }
 
         /**
-         * Cancels a pending or current upload for an account
+         * Cancels all the uploads for an account
          *
-         * @param account Owncloud accountName where the remote file will be stored.
+         * @param account   ownCloud account.
          */
         public void cancel(Account account) {
             Log_OC.d(TAG, "Account= " + account.name);
@@ -425,6 +416,7 @@ public class FileUploader extends Service
             mBoundListeners.clear();
         }
 
+
         /**
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
@@ -436,23 +428,6 @@ public class FileUploader extends Service
          * @param file      A file that could be in the queue of pending uploads
          */
         public boolean isUploading(Account account, OCFile file) {
-            /*
-            if (account == null || file == null)
-                return false;
-            String targetKey = buildRemoteName(account, file);
-            synchronized (mPendingUploads) {
-                if (file.isFolder()) {
-                    // this can be slow if there are many uploads :(
-                    Iterator<String> it = mPendingUploads.keySet().iterator();
-                    boolean found = false;
-                    while (it.hasNext() && !found) {
-                        found = it.next().startsWith(targetKey);
-                    }
-                    return found;
-                } else {
-                    return (mPendingUploads.containsKey(targetKey));
-                }
-            }*/
             if (account == null || file == null) return false;
             return (mPendingUploads.contains(account, file.getRemotePath()));
         }
@@ -503,15 +478,19 @@ public class FileUploader extends Service
         }
 
         /**
-         * Review uploads and cancel it if its account doesn't exist
+         * Builds a key for the map of listeners.
+         *
+         * TODO remove and replace key with file.getFileId() after changing current policy (upload file, then
+         * add to local database) to better policy (add to local database, then upload)
+         *
+         * @param account       ownCloud account where the file to upload belongs.
+         * @param file          File to upload
+         * @return              Key
          */
-        public void checkAccountOfCurrentUpload() {
-            if (mCurrentUpload != null &&
-                    !AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
-                mCurrentUpload.cancel();
-            }
-            // The rest of uploads are cancelled when they try to start
+        private String buildRemoteName(Account account, OCFile file) {
+            return account.name + file.getRemotePath();
         }
+
     }
 
     /**
@@ -570,16 +549,16 @@ public class FileUploader extends Service
 
                 try {
                     /// prepare client object to send the request to the ownCloud server
-                    if (mLastAccount == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
-                        mLastAccount = mCurrentUpload.getAccount();
+                    if (mCurrentAccount == null || !mCurrentAccount.equals(mCurrentUpload.getAccount())) {
+                        mCurrentAccount = mCurrentUpload.getAccount();
                         mStorageManager = new FileDataStorageManager(
-                                mLastAccount,
+                                mCurrentAccount,
                                 getContentResolver()
                         );
                     }   // else, reuse storage manager from previous operation
 
                     // always get client from client manager, to get fresh credentials in case of update
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
+                    OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
                     mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                             getClientFor(ocAccount, this);
 
@@ -606,19 +585,19 @@ public class FileUploader extends Service
 
                 } catch (AccountsException e) {
                     Log_OC.e(TAG, "Error while trying to get autorization for " +
-                            mLastAccount.name, e);
+                            mCurrentAccount.name, e);
                     uploadResult = new RemoteOperationResult(e);
 
                 } catch (IOException e) {
                     Log_OC.e(TAG, "Error while trying to get autorization for " +
-                            mLastAccount.name, e);
+                            mCurrentAccount.name, e);
                     uploadResult = new RemoteOperationResult(e);
 
                 } finally {
                     Log_OC.v("NOW " + TAG + ", thread " + Thread.currentThread().getName(),
                             "Removing payload " + mCurrentUpload.getRemotePath());
                     Pair<UploadFileOperation, String> removeResult =
-                            mPendingUploads.removePayload(mLastAccount, mCurrentUpload.getRemotePath());
+                            mPendingUploads.removePayload(mCurrentAccount, mCurrentUpload.getRemotePath());
 
                     /// notify result
                     notifyUploadResult(mCurrentUpload, uploadResult);
@@ -743,8 +722,7 @@ public class FileUploader extends Service
         file.setRemoteId(remoteFile.getRemoteId());
     }
 
-    private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
-                                           FileDataStorageManager storageManager) {
+    private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType) {
 
         // MIME type
         if (mimeType == null || mimeType.length() <= 0) {
@@ -980,6 +958,8 @@ public class FileUploader extends Service
      * @param localPath         Full path to a file in the local file system.
      * @param mimeType          MIME type of the file.
      * @return true if is needed to add the pdf file extension to the file
+     *
+     * TODO - move to OCFile or Utils class
      */
     private boolean isPdfFileFromContentProviderWithoutExtension(String localPath,
                                                                  String mimeType) {

+ 2 - 3
src/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -245,9 +245,8 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
                 dialog.show(getFragmentManager(), FTAG_RENAME_FILE);
                 return true;
             }
-            case R.id.action_cancel_download:
-            case R.id.action_cancel_upload: {
-                ((FileDisplayActivity) mContainerActivity).cancelTransference(getFile());
+            case R.id.action_cancel_sync: {
+                ((FileDisplayActivity)mContainerActivity).cancelTransference(getFile());
                 return true;
             }
             case R.id.action_download_file:

+ 2 - 3
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -371,9 +371,8 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
                 mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
                 return true;
             }
-            case R.id.action_cancel_download:
-            case R.id.action_cancel_upload: {
-                ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
+            case R.id.action_cancel_sync: {
+                ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
                 return true;
             }
             case R.id.action_see_details: {