Changes from Comments in PR#886
[pub/Android/ownCloud.git] / src / com / owncloud / android / files / services / FileUploader.java
index f9c57cc..d6ade1a 100644 (file)
@@ -1,6 +1,6 @@
 /* ownCloud Android client application
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2012-2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -56,6 +56,7 @@ import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
+import com.owncloud.android.lib.common.operations.OperationCancelledException;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
@@ -161,7 +162,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     @Override
     public void onCreate() {
         super.onCreate();
-        Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
+        Log_OC.d(TAG, "Creating service");
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
         HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
@@ -171,6 +172,21 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     }
 
     /**
+     * Service clean up
+     */
+    @Override
+    public void onDestroy() {
+        Log_OC.v(TAG, "Destroying service" );
+        mBinder = null;
+        mServiceHandler = null;
+        mServiceLooper.quit();
+        mServiceLooper = null;
+        mNotificationManager = null;
+        super.onDestroy();
+    }
+
+
+    /**
      * Entry point to add one or several files to the queue of uploads.
      *
      * New uploads are added calling to startService(), resulting in a call to
@@ -179,6 +195,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      */
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
+        Log_OC.d(TAG, "Starting command with id " + startId);
+
         if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_UPLOAD_TYPE)
                 || !(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) {
             Log_OC.e(TAG, "Not enough information provided in intent");
@@ -211,11 +229,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             if (intent.hasExtra(KEY_FILE)) {
                 files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE); // TODO
-                // will
-                // this
-                // casting
-                // work
-                // fine?
+                                                                             // will
+                                                                             // this
+                                                                             // casting
+                                                                             // work
+                                                                             // fine?
 
             } else {
                 localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
@@ -327,7 +345,6 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         return false;   // not accepting rebinding (default behaviour)
     }
 
-
     /**
      * Binder to let client components to perform operations on the queue of
      * uploads.
@@ -357,15 +374,28 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             }
         }
 
+        /**
+         * Cancels a pending or current upload for an account
+         *
+         * @param account Owncloud accountName where the remote file will be stored.
+         */
+        public void cancel(Account account) {
+            Log_OC.d(TAG, "Account= " + account.name);
 
+            if (mCurrentUpload != null) {
+                Log_OC.d(TAG, "Current Upload Account= " + mCurrentUpload.getAccount().name);
+                if (mCurrentUpload.getAccount().name.equals(account.name)) {
+                    mCurrentUpload.cancel();
+                }
+            }
+            // Cancel pending uploads
+            cancelUploadForAccount(account.name);
+        }
 
         public void clearListeners() {
             mBoundListeners.clear();
         }
 
-
-
-
         /**
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
@@ -436,6 +466,16 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             }
         }
 
+        /**
+         * Review uploads and cancel it if its account doesn't exist
+         */
+        public void checkAccountOfCurrentUpload() {
+            if (mCurrentUpload != null &&
+                    !AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
+                mCurrentUpload.cancel();
+            }
+            // The rest of uploads are cancelled when they try to start
+        }
     }
 
     /**
@@ -467,6 +507,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                     mService.uploadFile(it.next());
                 }
             }
+            Log_OC.d(TAG, "Stopping command after id " + msg.arg1);
             mService.stopSelf(msg.arg1);
         }
     }
@@ -487,7 +528,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             // Detect if the account exists
             if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
-                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() + " exists");
+                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().name + " exists");
 
                 notifyUploadStart(mCurrentUpload);
 
@@ -506,7 +547,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
                     /// check the existence of the parent folder for the file to upload
                     String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
-                    remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ? remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
+                    remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ?
+                            remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
                     grantResult = grantFolderExistence(remoteParentPath);
 
                     /// perform the upload
@@ -548,6 +590,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             } else {
                 // Cancel the transfer
                 Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() + " doesn't exist");
+                cancelUploadForAccount(mCurrentUpload.getAccount().name);
+
             }
         }
 
@@ -566,7 +610,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     private RemoteOperationResult grantFolderExistence(String pathToGrant) {
         RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, this, false);
         RemoteOperationResult result = operation.execute(mUploadClient);
-        if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mCurrentUpload.isRemoteFolderToBeCreated()) {
+        if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND &&
+                mCurrentUpload.isRemoteFolderToBeCreated()) {
             SyncOperation syncOp = new CreateFolderOperation( pathToGrant, true);
             result = syncOp.execute(mUploadClient, mStorageManager);
         }
@@ -587,7 +632,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     private OCFile createLocalFolder(String remotePath) {
         String parentPath = new File(remotePath).getParent();
-        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
+        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ?
+                parentPath : parentPath + OCFile.PATH_SEPARATOR;
         OCFile parent = mStorageManager.getFileByPath(parentPath);
         if (parent == null) {
             parent = createLocalFolder(parentPath);
@@ -887,4 +933,22 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 !localPath.endsWith(FILE_EXTENSION_PDF);
     }
 
+    /**
+     * Remove uploads of an account
+     * @param accountName
+     */
+    private void cancelUploadForAccount(String accountName){
+        // this can be slow if there are many uploads :(
+        Iterator<String> it = mPendingUploads.keySet().iterator();
+        Log_OC.d(TAG, "Number of pending updloads= "  + mPendingUploads.size());
+        while (it.hasNext()) {
+            String key = it.next();
+            Log_OC.d(TAG, "mPendingUploads CANCELLED " + key);
+            if (key.startsWith(accountName)) {
+                synchronized (mPendingUploads) {
+                    mPendingUploads.remove(key);
+                }
+            }
+        }
+    }
 }