Filter only '/' character in user input when version of server is 8.1 or later
[pub/Android/ownCloud.git] / src / com / owncloud / android / files / services / FileUploader.java
index f56e1b5..8beff92 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
  *   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,
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -31,6 +33,7 @@ import java.util.concurrent.ConcurrentMap;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AccountsException;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AccountsException;
+import android.accounts.OnAccountsUpdateListener;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -45,6 +48,7 @@ import android.os.Process;
 import android.support.v4.app.NotificationCompat;
 import android.webkit.MimeTypeMap;
 
 import android.support.v4.app.NotificationCompat;
 import android.webkit.MimeTypeMap;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
@@ -76,8 +80,8 @@ import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.UriUtils;
 
 
 import com.owncloud.android.utils.UriUtils;
 
 
-
-public class FileUploader extends Service implements OnDatatransferProgressListener {
+public class FileUploader extends Service
+        implements OnDatatransferProgressListener, OnAccountsUpdateListener {
 
     private static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
     public static final String EXTRA_UPLOAD_RESULT = "RESULT";
 
     private static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
     public static final String EXTRA_UPLOAD_RESULT = "RESULT";
@@ -161,15 +165,40 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     @Override
     public void onCreate() {
         super.onCreate();
     @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);
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND);
+        HandlerThread thread = new HandlerThread("FileUploaderThread",
+                Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
         mServiceLooper = thread.getLooper();
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileUploaderBinder();
         thread.start();
         mServiceLooper = thread.getLooper();
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileUploaderBinder();
+
+        // add AccountsUpdatedListener
+        AccountManager am = AccountManager.get(getApplicationContext());
+        am.addOnAccountsUpdatedListener(this, null, false);
+    }
+
+    /**
+     * Service clean up
+     */
+    @Override
+    public void onDestroy() {
+        Log_OC.v(TAG, "Destroying service" );
+        mBinder = null;
+        mServiceHandler = null;
+        mServiceLooper.quit();
+        mServiceLooper = null;
+        mNotificationManager = null;
+
+        // remove AccountsUpdatedListener
+        AccountManager am = AccountManager.get(getApplicationContext());
+        am.removeOnAccountsUpdatedListener(this);
+
+        super.onDestroy();
     }
 
     }
 
+
     /**
      * Entry point to add one or several files to the queue of uploads.
      *
     /**
      * Entry point to add one or several files to the queue of uploads.
      *
@@ -179,6 +208,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      */
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
      */
     @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");
         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 +242,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             if (intent.hasExtra(KEY_FILE)) {
                 files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE); // TODO
 
             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);
 
             } else {
                 localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
@@ -224,7 +255,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             }
         }
 
             }
         }
 
-        FileDataStorageManager storageManager = new FileDataStorageManager(account, getContentResolver());
+        FileDataStorageManager storageManager = new FileDataStorageManager(account,
+                getContentResolver());
 
         boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
         boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
 
         boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
         boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
@@ -250,8 +282,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             files = new OCFile[localPaths.length];
             for (int i = 0; i < localPaths.length; i++) {
 
             files = new OCFile[localPaths.length];
             for (int i = 0; i < localPaths.length; i++) {
-                files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i]
-                        : (String) null), storageManager);
+                files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i],
+                        ((mimeTypes != null) ? mimeTypes[i] : (String) null), storageManager);
                 if (files[i] == null) {
                     // TODO @andomaex add failure Notification
                     return Service.START_NOT_STICKY;
                 if (files[i] == null) {
                     // TODO @andomaex add failure Notification
                     return Service.START_NOT_STICKY;
@@ -270,12 +302,14 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         try {
             for (int i = 0; i < files.length; i++) {
                 uploadKey = buildRemoteName(account, files[i].getRemotePath());
         try {
             for (int i = 0; i < files.length; i++) {
                 uploadKey = buildRemoteName(account, files[i].getRemotePath());
-                newUpload = new UploadFileOperation(account, files[i], chunked, isInstant, forceOverwrite, localAction,
+                newUpload = new UploadFileOperation(account, files[i], chunked, isInstant,
+                        forceOverwrite, localAction,
                         getApplicationContext());
                 if (isInstant) {
                     newUpload.setRemoteFolderToBeCreated();
                 }
                         getApplicationContext());
                 if (isInstant) {
                     newUpload.setRemoteFolderToBeCreated();
                 }
-                mPendingUploads.putIfAbsent(uploadKey, newUpload); // Grants that the file only upload once time
+                // Grants that the file only upload once time
+                mPendingUploads.putIfAbsent(uploadKey, newUpload);
 
                 newUpload.addDatatransferProgressListener(this);
                 newUpload.addDatatransferProgressListener((FileUploaderBinder)mBinder);
 
                 newUpload.addDatatransferProgressListener(this);
                 newUpload.addDatatransferProgressListener((FileUploaderBinder)mBinder);
@@ -327,6 +361,16 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         return false;   // not accepting rebinding (default behaviour)
     }
 
         return false;   // not accepting rebinding (default behaviour)
     }
 
+    @Override
+    public void onAccountsUpdated(Account[] accounts) {
+        // Review current upload, and cancel it if its account doen't exist
+        if (mCurrentUpload != null &&
+                !AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
+            mCurrentUpload.cancel();
+        }
+        // The rest of uploads are cancelled when they try to start
+    }
+
     /**
      * Binder to let client components to perform operations on the queue of
      * uploads.
     /**
      * Binder to let client components to perform operations on the queue of
      * uploads.
@@ -336,7 +380,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     public class FileUploaderBinder extends Binder implements OnDatatransferProgressListener {
 
         /**
     public class FileUploaderBinder extends Binder implements OnDatatransferProgressListener {
 
         /**
-         * Map of listeners that will be reported about progress of uploads from a {@link FileUploaderBinder} instance 
+         * Map of listeners that will be reported about progress of uploads from a
+         * {@link FileUploaderBinder} instance
          */
         private Map<String, OnDatatransferProgressListener> mBoundListeners = new HashMap<String, OnDatatransferProgressListener>();
 
          */
         private Map<String, OnDatatransferProgressListener> mBoundListeners = new HashMap<String, OnDatatransferProgressListener>();
 
@@ -356,6 +401,24 @@ 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();
         }
         public void clearListeners() {
             mBoundListeners.clear();
         }
@@ -364,7 +427,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
          *
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
          *
-         * If 'file' is a directory, returns 'true' if some of its descendant files is uploading or waiting to upload. 
+         * If 'file' is a directory, returns 'true' if some of its descendant files
+         * is uploading or waiting to upload.
          *
          * @param account   ownCloud account where the remote file will be stored.
          * @param file      A file that could be in the queue of pending uploads
          *
          * @param account   ownCloud account where the remote file will be stored.
          * @param file      A file that could be in the queue of pending uploads
@@ -396,7 +460,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
          */
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
          */
-        public void addDatatransferProgressListener (OnDatatransferProgressListener listener, Account account, OCFile file) {
+        public void addDatatransferProgressListener (OnDatatransferProgressListener listener,
+                                                     Account account, OCFile file) {
             if (account == null || file == null || listener == null) return;
             String targetKey = buildRemoteName(account, file);
             mBoundListeners.put(targetKey, listener);
             if (account == null || file == null || listener == null) return;
             String targetKey = buildRemoteName(account, file);
             mBoundListeners.put(targetKey, listener);
@@ -411,7 +476,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
          */
          * @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) {
+        public void removeDatatransferProgressListener (OnDatatransferProgressListener listener,
+                                                        Account account, OCFile file) {
             if (account == null || file == null || listener == null) return;
             String targetKey = buildRemoteName(account, file);
             if (mBoundListeners.get(targetKey) == listener) {
             if (account == null || file == null || listener == null) return;
             String targetKey = buildRemoteName(account, file);
             if (mBoundListeners.get(targetKey) == listener) {
@@ -421,15 +487,26 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
 
         @Override
 
 
         @Override
-        public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
-                                       String fileName) {
+        public void onTransferProgress(long progressRate, long totalTransferredSoFar,
+                                       long totalToTransfer, String fileName) {
             String key = buildRemoteName(mCurrentUpload.getAccount(), mCurrentUpload.getFile());
             OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
             if (boundListener != null) {
             String key = buildRemoteName(mCurrentUpload.getAccount(), mCurrentUpload.getFile());
             OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
             if (boundListener != null) {
-                boundListener.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName);
+                boundListener.onTransferProgress(progressRate, totalTransferredSoFar,
+                        totalToTransfer, fileName);
             }
         }
 
             }
         }
 
+        /**
+         * 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
+        }
     }
 
     /**
     }
 
     /**
@@ -461,6 +538,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                     mService.uploadFile(it.next());
                 }
             }
                     mService.uploadFile(it.next());
                 }
             }
+            Log_OC.d(TAG, "Stopping command after id " + msg.arg1);
             mService.stopSelf(msg.arg1);
         }
     }
             mService.stopSelf(msg.arg1);
         }
     }
@@ -481,7 +559,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             // Detect if the account exists
             if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
 
             // 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);
 
 
                 notifyUploadStart(mCurrentUpload);
 
@@ -489,7 +567,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
                 try {
                     /// prepare client object to send requests to the ownCloud server
 
                 try {
                     /// prepare client object to send requests to the ownCloud server
-                    if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
+                    if (mUploadClient == null ||
+                            !mLastAccount.equals(mCurrentUpload.getAccount())) {
                         mLastAccount = mCurrentUpload.getAccount();
                         mStorageManager =
                                 new FileDataStorageManager(mLastAccount, getContentResolver());
                         mLastAccount = mCurrentUpload.getAccount();
                         mStorageManager =
                                 new FileDataStorageManager(mLastAccount, getContentResolver());
@@ -500,7 +579,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();
 
                     /// 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
                     grantResult = grantFolderExistence(remoteParentPath);
 
                     /// perform the upload
@@ -516,11 +596,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                     }
 
                 } catch (AccountsException e) {
                     }
 
                 } catch (AccountsException e) {
-                    Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+                    Log_OC.e(TAG, "Error while trying to get autorization for " +
+                            mLastAccount.name, e);
                     uploadResult = new RemoteOperationResult(e);
 
                 } catch (IOException e) {
                     uploadResult = new RemoteOperationResult(e);
 
                 } catch (IOException e) {
-                    Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+                    Log_OC.e(TAG, "Error while trying to get autorization for " +
+                            mLastAccount.name, e);
                     uploadResult = new RemoteOperationResult(e);
 
                 } finally {
                     uploadResult = new RemoteOperationResult(e);
 
                 } finally {
@@ -529,8 +611,9 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                         Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
                     }
                     if (uploadResult.isException()) {
                         Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
                     }
                     if (uploadResult.isException()) {
-                        // enforce the creation of a new client object for next uploads; this grant that a new socket will
-                        // be created in the future if the current exception is due to an abrupt lose of network connection
+                        // enforce the creation of a new client object for next uploads;
+                        // this grant that a new socket will be created in the future if
+                        // the current exception is due to an abrupt lose of network connection
                         mUploadClient = null;
                     }
                 }
                         mUploadClient = null;
                     }
                 }
@@ -541,7 +624,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             } else {
                 // Cancel the transfer
 
             } else {
                 // Cancel the transfer
-                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() + " doesn't exist");
+                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() +
+                        " doesn't exist");
                 cancelUploadForAccount(mCurrentUpload.getAccount().name);
 
             }
                 cancelUploadForAccount(mCurrentUpload.getAccount().name);
 
             }
@@ -550,19 +634,21 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     }
 
     /**
     }
 
     /**
-     * Checks the existence of the folder where the current file will be uploaded both in the remote server 
-     * and in the local database.
+     * Checks the existence of the folder where the current file will be uploaded both
+     * in the remote server and in the local database.
      *
      *
-     * If the upload is set to enforce the creation of the folder, the method tries to create it both remote
-     * and locally.
+     * If the upload is set to enforce the creation of the folder, the method tries to
+     * create it both remote and locally.
      *
      *  @param  pathToGrant     Full remote path whose existence will be granted.
      *
      *  @param  pathToGrant     Full remote path whose existence will be granted.
-     *  @return  An {@link OCFile} instance corresponding to the folder where the file will be uploaded.
+     *  @return  An {@link OCFile} instance corresponding to the folder where the file
+     *  will be uploaded.
      */
     private RemoteOperationResult grantFolderExistence(String pathToGrant) {
         RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, this, false);
         RemoteOperationResult result = operation.execute(mUploadClient);
      */
     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);
         }
             SyncOperation syncOp = new CreateFolderOperation( pathToGrant, true);
             result = syncOp.execute(mUploadClient, mStorageManager);
         }
@@ -583,7 +669,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     private OCFile createLocalFolder(String remotePath) {
         String parentPath = new File(remotePath).getParent();
 
     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);
         OCFile parent = mStorageManager.getFileByPath(parentPath);
         if (parent == null) {
             parent = createLocalFolder(parentPath);
@@ -618,7 +705,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         // new PROPFIND to keep data consistent with server 
         // in theory, should return the same we already have
 
         // new PROPFIND to keep data consistent with server 
         // in theory, should return the same we already have
-        ReadRemoteFileOperation operation = new ReadRemoteFileOperation(mCurrentUpload.getRemotePath());
+        ReadRemoteFileOperation operation =
+                new ReadRemoteFileOperation(mCurrentUpload.getRemotePath());
         RemoteOperationResult result = operation.execute(mUploadClient);
         if (result.isSuccess()) {
             updateOCFile(file, (RemoteFile) result.getData().get(0));
         RemoteOperationResult result = operation.execute(mUploadClient);
         if (result.isSuccess()) {
             updateOCFile(file, (RemoteFile) result.getData().get(0));
@@ -660,7 +748,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                         remotePath.substring(remotePath.lastIndexOf('.') + 1));
             } catch (IndexOutOfBoundsException e) {
                 mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                         remotePath.substring(remotePath.lastIndexOf('.') + 1));
             } catch (IndexOutOfBoundsException e) {
-                Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + remotePath);
+                Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " +
+                        remotePath);
             }
         }
         if (mimeType == null) {
             }
         }
         if (mimeType == null) {
@@ -725,11 +814,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      * Callback method to update the progress bar in the status notification
      */
     @Override
      * Callback method to update the progress bar in the status notification
      */
     @Override
-    public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath) {
+    public void onTransferProgress(long progressRate, long totalTransferredSoFar,
+                                   long totalToTransfer, String filePath) {
         int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         if (percent != mLastPercent) {
             mNotificationBuilder.setProgress(100, percent, false);
         int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         if (percent != mLastPercent) {
             mNotificationBuilder.setProgress(100, percent, false);
-            String fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1);
+            String fileName = filePath.substring(
+                    filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1);
             String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName);
             mNotificationBuilder.setContentText(text);
             mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
             String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName);
             mNotificationBuilder.setContentText(text);
             mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
@@ -877,7 +968,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      * @param mimeType
      * @return true if is needed to add the pdf file extension to the file
      */
      * @param mimeType
      * @return true if is needed to add the pdf file extension to the file
      */
-    private boolean isPdfFileFromContentProviderWithoutExtension(String localPath, String mimeType) {
+    private boolean isPdfFileFromContentProviderWithoutExtension(String localPath,
+                                                                 String mimeType) {
         return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) &&
                 mimeType.equals(MIME_TYPE_PDF) &&
                 !localPath.endsWith(FILE_EXTENSION_PDF);
         return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) &&
                 mimeType.equals(MIME_TYPE_PDF) &&
                 !localPath.endsWith(FILE_EXTENSION_PDF);
@@ -891,12 +983,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         // 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());
         // 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());
-        boolean found;
         while (it.hasNext()) {
             String key = it.next();
         while (it.hasNext()) {
             String key = it.next();
-            Log_OC.d(TAG, "mPendingUploads CANCELLED" + key);
+            Log_OC.d(TAG, "mPendingUploads CANCELLED " + key);
             if (key.startsWith(accountName)) {
             if (key.startsWith(accountName)) {
-                mPendingUploads.remove(key);
+                synchronized (mPendingUploads) {
+                    mPendingUploads.remove(key);
+                }
             }
         }
     }
             }
         }
     }