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

Merged FileUploadService into FileUploader to avoid that changes from other branches are circumvented

David A. Velasco 9 жил өмнө
parent
commit
40e9bb0529
24 өөрчлөгдсөн 753 нэмэгдсэн , 2242 устгасан
  1. 1 1
      AndroidManifest.xml
  2. 71 0
      src/com/owncloud/android/datamodel/UploadsStorageManager.java
  3. 98 2
      src/com/owncloud/android/db/OCUpload.java
  4. 2 3
      src/com/owncloud/android/files/FileMenuFilter.java
  5. 1 1
      src/com/owncloud/android/files/FileOperationsHelper.java
  6. 19 19
      src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java
  7. 3 3
      src/com/owncloud/android/files/services/ConnectivityActionReceiver.java
  8. 1 1
      src/com/owncloud/android/files/services/FileDownloader.java
  9. 0 2000
      src/com/owncloud/android/files/services/FileUploadService.java
  10. 467 120
      src/com/owncloud/android/files/services/FileUploader.java
  11. 7 7
      src/com/owncloud/android/operations/SynchronizeFileOperation.java
  12. 4 4
      src/com/owncloud/android/operations/UploadFileOperation.java
  13. 1 1
      src/com/owncloud/android/ui/activity/ComponentsGetter.java
  14. 7 7
      src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java
  15. 3 3
      src/com/owncloud/android/ui/activity/FileActivity.java
  16. 27 27
      src/com/owncloud/android/ui/activity/FileDisplayActivity.java
  17. 7 8
      src/com/owncloud/android/ui/activity/Preferences.java
  18. 7 7
      src/com/owncloud/android/ui/activity/UploadListActivity.java
  19. 13 13
      src/com/owncloud/android/ui/activity/Uploader.java
  20. 5 5
      src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java
  21. 1 1
      src/com/owncloud/android/ui/adapter/FileListListAdapter.java
  22. 3 3
      src/com/owncloud/android/ui/fragment/FileDetailFragment.java
  23. 1 1
      src/com/owncloud/android/ui/fragment/FileFragment.java
  24. 4 5
      src/com/owncloud/android/ui/preview/PreviewImageActivity.java

+ 1 - 1
AndroidManifest.xml

@@ -145,7 +145,7 @@
 
 
         <service android:name=".services.OperationsService" />
         <service android:name=".services.OperationsService" />
         <service android:name=".files.services.FileDownloader" />
         <service android:name=".files.services.FileDownloader" />
-        <service android:name=".files.services.FileUploadService" />
+        <service android:name=".files.services.FileUploader" />
         <service android:name=".media.MediaService" />
         <service android:name=".media.MediaService" />
 
 
         <activity android:name=".ui.activity.PassCodeActivity" />
         <activity android:name=".ui.activity.PassCodeActivity" />

+ 71 - 0
src/com/owncloud/android/datamodel/UploadsStorageManager.java

@@ -28,7 +28,9 @@ import android.net.Uri;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.db.UploadResult;
 import com.owncloud.android.db.UploadResult;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.UploadFileOperation;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 
 
 import java.io.File;
 import java.io.File;
@@ -573,4 +575,73 @@ public class UploadsStorageManager extends Observable {
         updateUploadInternal(c, UploadStatus.UPLOAD_LATER, UploadResult.UNKNOWN);
         updateUploadInternal(c, UploadStatus.UPLOAD_LATER, UploadResult.UNKNOWN);
     }
     }
 
 
+
+    /**
+     * Updates the persistent upload database with upload result.
+     */
+    public void updateDatabaseUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
+        // result: success or fail notification
+        Log_OC.d(TAG, "updateDataseUploadResult uploadResult: " + uploadResult + " upload: " + upload);
+        if (uploadResult.isCancelled()) {
+            updateUploadStatus(
+                    upload.getOCUploadId(),
+                    UploadStatus.UPLOAD_CANCELLED,
+                    UploadResult.CANCELLED
+            );
+        } else {
+
+            if (uploadResult.isSuccess()) {
+                updateUploadStatus(
+                        upload.getOCUploadId(),
+                        UploadStatus.UPLOAD_SUCCEEDED,
+                        UploadResult.UPLOADED
+                );
+            } else {
+                // TODO: Disable for testing of menu actions in uploads view
+                if (shouldRetryFailedUpload(uploadResult)) {
+                    updateUploadStatus(
+                            upload.getOCUploadId(), UploadStatus.UPLOAD_FAILED_RETRY,
+                            UploadResult.fromOperationResult(uploadResult));
+                } else {
+                    updateUploadStatus(upload.getOCUploadId(),
+                            UploadsStorageManager.UploadStatus.UPLOAD_FAILED_GIVE_UP,
+                            UploadResult.fromOperationResult(uploadResult));
+                }
+            }
+        }
+    }
+
+    /**
+     * Determines whether with given uploadResult the upload should be retried later.
+     * @param uploadResult
+     * @return true if upload should be retried later, false if is should be abandoned.
+     */
+    private boolean shouldRetryFailedUpload(RemoteOperationResult uploadResult) {
+        if (uploadResult.isSuccess()) {
+            return false;
+        }
+        switch (uploadResult.getCode()) {
+            case HOST_NOT_AVAILABLE:
+            case NO_NETWORK_CONNECTION:
+            case TIMEOUT:
+            case WRONG_CONNECTION: // SocketException
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Updates the persistent upload database that upload is in progress.
+     */
+    public void updateDatabaseUploadStart(UploadFileOperation upload) {
+        updateUploadStatus(
+                upload.getOCUploadId(),
+                UploadStatus.UPLOAD_IN_PROGRESS,
+                UploadResult.UNKNOWN
+        );
+    }
+
+
+
 }
 }

+ 98 - 2
src/com/owncloud/android/db/OCUpload.java

@@ -25,14 +25,19 @@ import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.Parcelable;
 
 
+import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
 import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.UploadUtils;
 
 
+import java.io.File;
 import java.util.Calendar;
 import java.util.Calendar;
+import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.GregorianCalendar;
 
 
 /**
 /**
@@ -101,7 +106,7 @@ public class OCUpload implements Parcelable{
     // TODO needed???
     // TODO needed???
     private void resetData(){
     private void resetData(){
         mId = -1;
         mId = -1;
-        mLocalAction = FileUploadService.LOCAL_BEHAVIOUR_COPY;
+        mLocalAction = FileUploader.LOCAL_BEHAVIOUR_COPY;
         mUploadTime = new GregorianCalendar();
         mUploadTime = new GregorianCalendar();
         mForceOverwrite = false;
         mForceOverwrite = false;
         mIsCreateRemoteFolder = false;
         mIsCreateRemoteFolder = false;
@@ -408,4 +413,95 @@ public class OCUpload implements Parcelable{
         dest.writeString(mUploadStatus.name());
         dest.writeString(mUploadStatus.name());
         dest.writeString(((mLastResult == null) ? "" : mLastResult.name()));
         dest.writeString(((mLastResult == null) ? "" : mLastResult.name()));
     }
     }
+
+
+    enum CanUploadFileNowStatus {NOW, LATER, FILE_GONE, ERROR};
+
+    /**
+     * Returns true when the file may be uploaded now. This methods checks all
+     * restraints of the passed {@link OCUpload}, these include
+     * isUseWifiOnly(), check if local file exists, check if file was already
+     * uploaded...
+     *
+     * If return value is CanUploadFileNowStatus.NOW, uploadFile() may be
+     * called.
+     *
+     * @return CanUploadFileNowStatus.NOW is upload may proceed, <br>
+     *         CanUploadFileNowStatus.LATER if upload should be performed at a
+     *         later time, <br>
+     *         CanUploadFileNowStatus.ERROR if a severe error happened, calling
+     *         entity should remove upload from queue.
+     *
+     */
+    private CanUploadFileNowStatus canUploadFileNow(Context context) {
+
+        if (getUploadStatus() == UploadStatus.UPLOAD_SUCCEEDED) {
+            Log_OC.w(TAG, "Already succeeded uploadObject was again scheduled for upload. Fix that!");
+            return CanUploadFileNowStatus.ERROR;
+        }
+
+        if (isUseWifiOnly()
+                && !UploadUtils.isConnectedViaWiFi(context)) {
+            Log_OC.d(TAG, "Do not start upload because it is wifi-only.");
+            return CanUploadFileNowStatus.LATER;
+        }
+
+        if(isWhileChargingOnly() && !UploadUtils.isCharging(context)) {
+            Log_OC.d(TAG, "Do not start upload because it is while charging only.");
+            return CanUploadFileNowStatus.LATER;
+        }
+        Date now = new Date();
+        if (now.getTime() < getUploadTimestamp()) {
+            Log_OC.d(
+                    TAG,
+                    "Do not start upload because it is schedule for "
+                            + DisplayUtils.unixTimeToHumanReadable(getUploadTimestamp()));
+            return CanUploadFileNowStatus.LATER;
+        }
+
+
+        if (!new File(getLocalPath()).exists()) {
+            Log_OC.d(TAG, "Do not start upload because local file does not exist.");
+            return CanUploadFileNowStatus.FILE_GONE;
+        }
+        return CanUploadFileNowStatus.NOW;
+    }
+
+
+    /**
+     * Returns the reason as String why state of OCUpload is LATER. If
+     * upload state != LATER return null.
+     */
+    public String getUploadLaterReason(Context context) {
+        StringBuilder reason = new StringBuilder();
+        Date now = new Date();
+        if (now.getTime() < getUploadTimestamp()) {
+            reason.append(context.getString(R.string.uploads_view_later_reason_waiting_for) +
+                    DisplayUtils.unixTimeToHumanReadable(getUploadTimestamp()));
+        }
+        if (isUseWifiOnly() && !UploadUtils.isConnectedViaWiFi(context)) {
+            if (reason.length() > 0) {
+                reason.append(context.getString(R.string.uploads_view_later_reason_add_wifi_reason));
+            } else {
+                reason.append(context.getString(R.string.uploads_view_later_reason_waiting_for_wifi));
+            }
+        }
+        if (isWhileChargingOnly() && !UploadUtils.isCharging(context)) {
+            if (reason.length() > 0) {
+                reason.append(context.getString(R.string.uploads_view_later_reason_add_charging_reason));
+            } else {
+                reason.append(context.getString(R.string.uploads_view_later_reason_waiting_for_charging));
+            }
+        }
+        reason.append(".");
+        if (reason.length() > 1) {
+            return reason.toString();
+        }
+        if (getUploadStatus() == UploadStatus.UPLOAD_LATER) {
+            return context.getString(R.string.uploads_view_later_waiting_to_upload);
+        }
+        return null;
+    }
+
+
 }
 }

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

@@ -29,8 +29,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.ui.activity.ComponentsGetter;
@@ -55,7 +54,7 @@ public class FileMenuFilter {
      * @param targetFile        {@link OCFile} target of the action to filter in the {@link Menu}.
      * @param targetFile        {@link OCFile} target of the action to filter in the {@link Menu}.
      * @param account           ownCloud {@link Account} holding targetFile.
      * @param account           ownCloud {@link Account} holding targetFile.
      * @param cg                Accessor to app components, needed to access the
      * @param cg                Accessor to app components, needed to access the
-     *                          {@link FileUploadService} and {@link FileDownloader} services
+     *                          {@link FileUploader} and {@link FileDownloader} services
      * @param context           Android {@link Context}, needed to access build setup resources.
      * @param context           Android {@link Context}, needed to access build setup resources.
      */
      */
     public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg,
     public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg,

+ 1 - 1
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -38,7 +38,7 @@ import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.network.WebdavUtils;
 import com.owncloud.android.lib.common.network.WebdavUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.OCShare;

+ 19 - 19
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java

@@ -31,7 +31,7 @@ import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Video;
 import android.provider.MediaStore.Video;
 
 
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AccountUtils;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.FileStorageUtils;
 
 
@@ -112,14 +112,14 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         lastUploadedPhotoPath = file_path;
         lastUploadedPhotoPath = file_path;
         Log_OC.d(TAG, "Path: " + file_path + "");        
         Log_OC.d(TAG, "Path: " + file_path + "");        
         
         
-        Intent i = new Intent(context, FileUploadService.class);
-        i.putExtra(FileUploadService.KEY_ACCOUNT, account);
-        i.putExtra(FileUploadService.KEY_LOCAL_FILE, file_path);
-        i.putExtra(FileUploadService.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
-        i.putExtra(FileUploadService.KEY_UPLOAD_TYPE, FileUploadService.UPLOAD_SINGLE_FILE);
-        i.putExtra(FileUploadService.KEY_MIME_TYPE, mime_type);
-        i.putExtra(FileUploadService.KEY_CREATE_REMOTE_FOLDER, true);
-        i.putExtra(FileUploadService.KEY_WIFI_ONLY, instantPictureUploadViaWiFiOnly(context));
+        Intent i = new Intent(context, FileUploader.class);
+        i.putExtra(FileUploader.KEY_ACCOUNT, account);
+        i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
+        i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
+        i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
+        i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
+        i.putExtra(FileUploader.KEY_CREATE_REMOTE_FOLDER, true);
+        i.putExtra(FileUploader.KEY_WIFI_ONLY, instantPictureUploadViaWiFiOnly(context));
 
 
 // On master
 // On master
 //        Intent i = new Intent(context, FileUploader.class);
 //        Intent i = new Intent(context, FileUploader.class);
@@ -142,9 +142,9 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
 
 
         if (behaviour.equalsIgnoreCase("NOTHING")) {
         if (behaviour.equalsIgnoreCase("NOTHING")) {
             Log_OC.d(TAG, "upload file and do nothing");
             Log_OC.d(TAG, "upload file and do nothing");
-            i.putExtra(FileUploadService.KEY_LOCAL_BEHAVIOUR, FileUploadService.LOCAL_BEHAVIOUR_FORGET);
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_FORGET);
         } else if (behaviour.equalsIgnoreCase("MOVE")) {
         } else if (behaviour.equalsIgnoreCase("MOVE")) {
-            i.putExtra(FileUploadService.KEY_LOCAL_BEHAVIOUR, FileUploadService.LOCAL_BEHAVIOUR_MOVE);
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
             Log_OC.d(TAG, "upload file and move file to oc folder");
             Log_OC.d(TAG, "upload file and move file to oc folder");
         }
         }
         return i;
         return i;
@@ -182,14 +182,14 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         c.close();
         c.close();
         Log_OC.d(TAG, file_path + "");
         Log_OC.d(TAG, file_path + "");
 
 
-        Intent i = new Intent(context, FileUploadService.class);
-        i.putExtra(FileUploadService.KEY_ACCOUNT, account);
-        i.putExtra(FileUploadService.KEY_LOCAL_FILE, file_path);
-        i.putExtra(FileUploadService.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
-        i.putExtra(FileUploadService.KEY_UPLOAD_TYPE, FileUploadService.UPLOAD_SINGLE_FILE);
-        i.putExtra(FileUploadService.KEY_MIME_TYPE, mime_type);
-        i.putExtra(FileUploadService.KEY_CREATE_REMOTE_FOLDER, true);
-        i.putExtra(FileUploadService.KEY_WIFI_ONLY, instantVideoUploadViaWiFiOnly(context));
+        Intent i = new Intent(context, FileUploader.class);
+        i.putExtra(FileUploader.KEY_ACCOUNT, account);
+        i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
+        i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, file_name));
+        i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
+        i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
+        i.putExtra(FileUploader.KEY_CREATE_REMOTE_FOLDER, true);
+        i.putExtra(FileUploader.KEY_WIFI_ONLY, instantVideoUploadViaWiFiOnly(context));
         context.startService(i);
         context.startService(i);
 // On master
 // On master
 //        if (!isOnline(context) || (instantVideoUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))) {
 //        if (!isOnline(context) || (instantVideoUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))) {

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

@@ -35,7 +35,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 /**
 /**
  * Receives all connectivity action from Android OS at all times and performs
  * Receives all connectivity action from Android OS at all times and performs
  * required OC actions. For now that are: - Signal connectivity to
  * required OC actions. For now that are: - Signal connectivity to
- * {@link FileUploadService}.
+ * {@link FileUploader}.
  * 
  * 
  * Later can be added: - Signal connectivity to download service, deletion
  * Later can be added: - Signal connectivity to download service, deletion
  * service, ... - Handle offline mode (cf.
  * service, ... - Handle offline mode (cf.
@@ -87,8 +87,8 @@ public class ConnectivityActionReceiver extends BroadcastReceiver {
     }
     }
 
 
 //    private void wifiConnected(Context context) {
 //    private void wifiConnected(Context context) {
-//        Log_OC.d(TAG, "FileUploadService.retry() called by onReceive()");
-//      FileUploadService.retry(context);
+//        Log_OC.d(TAG, "FileUploader.retry() called by onReceive()");
+//      FileUploader.retry(context);
 //    }
 //    }
 
 
     private void wifiDisconnected(Context context) {
     private void wifiDisconnected(Context context) {

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

@@ -353,7 +353,7 @@ public class FileDownloader extends Service
     /**
     /**
      * Download worker. Performs the pending downloads in the order they were requested.
      * Download worker. Performs the pending downloads in the order they were requested.
 
 
-     * Created with the Looper of a new thread, started in {@link FileUploadService#onCreate()}.
+     * Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}.
      */
      */
     private static class ServiceHandler extends Handler {
     private static class ServiceHandler extends Handler {
         // don't make it a final class, and don't remove the static ; lint will warn about a
         // don't make it a final class, and don't remove the static ; lint will warn about a

+ 0 - 2000
src/com/owncloud/android/files/services/FileUploadService.java

@@ -1,2000 +0,0 @@
-/**
- *   ownCloud Android client application
- *
- *   @author LukeOwncloud
- *   @author masensio
- *   Copyright (C) 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,
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package com.owncloud.android.files.services;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.OnAccountsUpdateListener;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.support.v4.app.NotificationCompat;
-import android.util.Pair;
-import android.webkit.MimeTypeMap;
-
-import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountUtils;
-import com.owncloud.android.authentication.AuthenticatorActivity;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.datamodel.UploadsStorageManager;
-import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
-import com.owncloud.android.db.OCUpload;
-import com.owncloud.android.db.UploadResult;
-import com.owncloud.android.lib.common.OwnCloudAccount;
-import com.owncloud.android.lib.common.OwnCloudClient;
-import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
-import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
-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;
-import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
-import com.owncloud.android.lib.resources.files.FileUtils;
-import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
-import com.owncloud.android.lib.resources.files.RemoteFile;
-import com.owncloud.android.lib.resources.status.OwnCloudVersion;
-import com.owncloud.android.notifications.NotificationBuilderWithProgressBar;
-import com.owncloud.android.notifications.NotificationDelayer;
-import com.owncloud.android.operations.CreateFolderOperation;
-import com.owncloud.android.operations.UploadFileOperation;
-import com.owncloud.android.operations.common.SyncOperation;
-import com.owncloud.android.ui.activity.FileActivity;
-import com.owncloud.android.ui.activity.UploadListActivity;
-import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.ErrorMessageAdapter;
-import com.owncloud.android.utils.UploadUtils;
-import com.owncloud.android.utils.UriUtils;
-
-import java.io.File;
-import java.util.AbstractList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Service for uploading files. Invoke using context.startService(...). Files to
- * be uploaded are stored persistently using {@link UploadsStorageManager}.
- * 
- * On next invocation of {@link FileUploadService} uploaded files which
- * previously failed will be uploaded again until either upload succeeded or a
- * fatal error occured.
- * 
- * Every file passed to this service is uploaded. No filtering is performed.
- * However, Intent keys (e.g., KEY_WIFI_ONLY) are obeyed.
- * 
- */
-public class FileUploadService extends Service implements OnDatatransferProgressListener,
-        OnAccountsUpdateListener {
-
-    private static final String TAG = FileUploadService.class.getSimpleName();
-
-    private static final String UPLOAD_START_MESSAGE = "UPLOAD_START";
-    private static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
-    public static final String EXTRA_UPLOAD_RESULT = "RESULT";
-    public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
-    public static final String EXTRA_OLD_REMOTE_PATH = "OLD_REMOTE_PATH";
-    public static final String EXTRA_OLD_FILE_PATH = "OLD_FILE_PATH";
-    public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
-
-    public static final String KEY_FILE = "FILE";
-    public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
-    public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
-    public static final String KEY_MIME_TYPE = "MIME_TYPE";
-
-    /**
-     * Call this Service with only this Intent key if all pending uploads are to be retried.
-     */
-    private static final String KEY_RETRY = "KEY_RETRY";
-//    /**
-//     * Call this Service with KEY_RETRY and KEY_RETRY_REMOTE_PATH to retry
-//     * upload of file identified by KEY_RETRY_REMOTE_PATH.
-//     */
-//    private static final String KEY_RETRY_REMOTE_PATH = "KEY_RETRY_REMOTE_PATH";
-    /**
-     * Call this Service with KEY_RETRY and KEY_RETRY_UPLOAD to retry
-     * upload of file identified by KEY_RETRY_UPLOAD.
-     */
-    private static final String KEY_RETRY_UPLOAD = "KEY_RETRY_UPLOAD";
-    /**
-     * {@link Account} to which file is to be uploaded.
-     */
-    public static final String KEY_ACCOUNT = "ACCOUNT";
-    /**
-     * Set whether single file or multiple files are to be uploaded. SINGLE_FILES = 0, MULTIPLE_FILEs = 1.
-     */
-    public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
-    /**
-     * Set to true if remote file is to be overwritten. Default action is to upload with different name.
-     */
-    public static final String KEY_FORCE_OVERWRITE = "KEY_FORCE_OVERWRITE";
-    /**
-     * Set to true if remote folder is to be created if it does not exist.
-     */
-    public static final String KEY_CREATE_REMOTE_FOLDER = "CREATE_REMOTE_FOLDER";
-    /**
-     * Set to true if upload is to performed only when connected via wifi.
-     */
-    public static final String KEY_WIFI_ONLY = "WIFI_ONLY";
-    /**
-     * Set to true if upload is to performed only when phone is being charged.
-     */
-    public static final String KEY_WHILE_CHARGING_ONLY = "KEY_WHILE_CHARGING_ONLY";
-//    /**
-//     * Set to future UNIX timestamp. Upload will not be performed before this timestamp.
-//     */
-//    public static final String KEY_UPLOAD_TIMESTAMP= "KEY_UPLOAD_TIMESTAMP";
-
-    public static final String KEY_LOCAL_BEHAVIOUR = "BEHAVIOUR";
-
-    //public static final String KEY_INSTANT_UPLOAD = "INSTANT_UPLOAD";
-
-    public static final int LOCAL_BEHAVIOUR_COPY = 0;
-    public static final int LOCAL_BEHAVIOUR_MOVE = 1;
-    public static final int LOCAL_BEHAVIOUR_FORGET = 2;
-
-    public static final int UPLOAD_SINGLE_FILE = 0;
-    public static final int UPLOAD_MULTIPLE_FILES = 1;
-
-    /**
-     * Describes local behavior for upload.
-     */
-//    public enum LocalBehaviour {
-//        /**
-//         * Creates a copy of file and stores it in tmp folder inside owncloud
-//         * folder on sd-card. After upload it is moved to local owncloud
-//         * storage. Original file stays untouched.
-//         */
-//        LOCAL_BEHAVIOUR_COPY(0),
-//        /**
-//         * Upload file from current storage. Afterwards original file is move to
-//         * local owncloud storage.
-//         */
-//        LOCAL_BEHAVIOUR_MOVE(1),
-//        /**
-//         * Just uploads file and leaves it where it is. Original file stays
-//         * untouched.
-//         */
-//        LOCAL_BEHAVIOUR_FORGET(2);
-//        private final int value;
-//
-//        LocalBehaviour(int value) {
-//            this.value = value;
-//        }
-//
-//        public int getValue() {
-//            return value;
-//        }
-//
-//        public static LocalBehaviour fromValue(int value){
-//            switch (value)
-//            {
-//                case 0:
-//                    return LOCAL_BEHAVIOUR_COPY;
-//                case 1:
-//                    return LOCAL_BEHAVIOUR_MOVE;
-//                case 2:
-//                    return LOCAL_BEHAVIOUR_FORGET;
-//            }
-//            return null;
-//        }
-//    }
-
-//    public enum UploadQuantity {
-//        UPLOAD_SINGLE_FILE(0), UPLOAD_MULTIPLE_FILES(1);
-//        private final int value;
-//
-//        UploadQuantity(int value) {
-//            this.value = value;
-//        }
-//
-//        public int getValue() {
-//            return value;
-//        }
-//    };
-
-    private Looper mServiceLooper;
-    private ServiceHandler mServiceHandler;
-    //private ExecutorService mUploadExecutor;
-
-    private IBinder mBinder;
-    private OwnCloudClient mUploadClient = null;
-    private Account mCurrentAccount = null;
-    private FileDataStorageManager mStorageManager;
-    //since there can be only one instance of an Android service, there also just one db connection.
-    private UploadsStorageManager mUploadsStorageManager = null;
-
-    private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
-    //private final AtomicBoolean mCancellationPossible = new AtomicBoolean(false);
-
-    /**
-     * List of uploads that are currently pending. Maps from remotePath to where file
-     * is being uploaded to {@link UploadFileOperation}.
-     */
-    //private ConcurrentMap<String, OCUpload> mPendingUploads = new ConcurrentHashMap<String, OCUpload>();
-    // TODO: change kind of mPendingUploads: List to IndexedForest
-    private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<UploadFileOperation>();
-
-    /**
-     * {@link UploadFileOperation} object of ongoing upload. Can be null. Note: There can only be one concurrent upload!
-     */
-    private UploadFileOperation mCurrentUpload = null;
-
-    private NotificationManager mNotificationManager;
-    private NotificationCompat.Builder mNotificationBuilder;
-    private int mLastPercent;
-
-    private static final String MIME_TYPE_PDF = "application/pdf";
-    private static final String FILE_EXTENSION_PDF = ".pdf";
-
-    public static String getUploadStartMessage() {
-        return FileUploadService.class.getName() + UPLOAD_START_MESSAGE;
-    }
-
-    public static String getUploadFinishMessage() {
-        return FileUploadService.class.getName() + UPLOAD_FINISH_MESSAGE;
-    }
-
-    /**
-     * Checks if an ownCloud server version should support chunked uploads.
-     *
-     * @param version OwnCloud version instance corresponding to an ownCloud
-     *                server.
-     * @return 'True' if the ownCloud server with version supports chunked
-     * uploads.
-     * <p/>
-     * TODO - move to OCClient
-     */
-    private static boolean chunkedUploadIsSupported(OwnCloudVersion version) {
-        return (version != null && version.compareTo(OwnCloudVersion.owncloud_v4_5) >= 0);
-    }
-
-    /**
-     * Service initialization
-     */
-    // TODO: Clean method: comments on extra code
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        Log_OC.d(TAG, "Creating service");
-        //Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - onCreate");
-        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        // HandlerThread thread = new HandlerThread("FileUploadService-Requester"); --> From FileUploadService
-        HandlerThread thread = new HandlerThread("FileUploaderThread",
-                android.os.Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-        mServiceLooper = thread.getLooper();
-        //mServiceHandler = new ServiceHandler(mServiceLooper); // FileUploaderService
-        mServiceHandler = new ServiceHandler(mServiceLooper, this); // FileUploader
-        mBinder = new FileUploaderBinder();
-
-        // From FileUploaderService
-        mUploadsStorageManager = new UploadsStorageManager(getContentResolver());
-
-        //when this service starts there is no upload in progress. if db says so, app probably crashed before.
-        mUploadsStorageManager.setAllCurrentToUploadLater();
-
-        // mUploadExecutor = Executors.newFixedThreadPool(1);
-
-//        Log_OC.d(TAG, "FileUploadService.retry() called by onCreate()");
-//        FileUploadService.retry(getApplicationContext());
-
-        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;
-
-        // From FileUploader
-        //Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - onDestroy");
-        Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.toString() + " - onDestroy");
-        //mServiceLooper.quit();
-        //mUploadExecutor.shutdown();
-
-        AccountManager am = AccountManager.get(getApplicationContext());
-        am.removeOnAccountsUpdatedListener(this);
-
-        super.onDestroy();
-
-    }
-
-    // Deprecated: TODO - Remove, not in FileUploader
-//    @Override
-//    public void onStart(Intent intent, int intentStartId) {
-//        Message msg = mServiceHandler.obtainMessage();
-//        msg.arg1 = intentStartId;
-//        msg.obj = intent;
-//        mServiceHandler.sendMessage(msg);
-//    }
-
-    /**
-     * Entry point to add one or several files to the queue of uploads.
-     * <p/>
-     * New uploads 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.
-     */
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        Log_OC.d(TAG, "Starting command with id " + startId);
-
-        boolean retry = intent.getBooleanExtra(KEY_RETRY, false);
-        AbstractList<String> requestedUploads = new Vector<String>();
-
-        if (!intent.hasExtra(KEY_ACCOUNT)) {
-            Log_OC.e(TAG, "Not enough information provided in intent");
-            return Service.START_NOT_STICKY;
-
-        } else {
-            Account account = intent.getParcelableExtra(KEY_ACCOUNT);
-            if (!AccountUtils.exists(account, getApplicationContext())) {
-                return Service.START_NOT_STICKY;
-            }
-            OwnCloudVersion ocv = AccountUtils.getServerVersion(account);
-            boolean chunked = FileUploadService.chunkedUploadIsSupported(ocv);
-
-            if (!retry) {
-                if (!intent.hasExtra(KEY_UPLOAD_TYPE) || !(intent.hasExtra(KEY_LOCAL_FILE) ||
-                        intent.hasExtra(KEY_FILE))) {
-                    Log_OC.e(TAG, "Not enough information provided in intent");
-                    return Service.START_NOT_STICKY;
-                }
-                int uploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
-                if (uploadType == -1) {
-                    Log_OC.e(TAG, "Incorrect upload type provided");
-                    return Service.START_NOT_STICKY;
-                }
-
-                String[] localPaths = null, remotePaths = null, mimeTypes = null;
-                OCFile[] files = null;
-                if (uploadType == UPLOAD_SINGLE_FILE) {
-
-                    if (intent.hasExtra(KEY_FILE)) {
-                        files = new OCFile[]{intent.getParcelableExtra(KEY_FILE)};
-
-                    } else {
-                        localPaths = new String[]{intent.getStringExtra(KEY_LOCAL_FILE)};
-                        remotePaths = new String[]{intent.getStringExtra(KEY_REMOTE_FILE)};
-                        mimeTypes = new String[]{intent.getStringExtra(KEY_MIME_TYPE)};
-                    }
-
-                } else { // mUploadType == UPLOAD_MULTIPLE_FILES
-
-                    if (intent.hasExtra(KEY_FILE)) {
-                        files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE); // TODO
-                        // will
-                        // this
-                        // casting
-                        // work
-                        // fine?
-
-                    } else {
-                        localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
-                        remotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
-                        mimeTypes = intent.getStringArrayExtra(KEY_MIME_TYPE);
-                    }
-                }
-
-                mStorageManager = new FileDataStorageManager(account, getContentResolver());
-
-                boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
-                int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_FORGET);
-
-                boolean isCreateRemoteFolder = intent.getBooleanExtra(KEY_CREATE_REMOTE_FOLDER, false);
-                boolean isUseWifiOnly = intent.getBooleanExtra(KEY_WIFI_ONLY, true);
-                boolean isWhileChargingOnly = intent.getBooleanExtra(KEY_WHILE_CHARGING_ONLY, false);
-                //long uploadTimestamp = intent.getLongExtra(KEY_UPLOAD_TIMESTAMP, -1);
-
-
-                if (intent.hasExtra(KEY_FILE) && files == null) {
-                    Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
-                    return Service.START_NOT_STICKY;
-
-                } else if (!intent.hasExtra(KEY_FILE)) {
-                    if (localPaths == null) {
-                        Log_OC.e(TAG, "Incorrect array for local paths provided in upload intent");
-                        return Service.START_NOT_STICKY;
-                    }
-                    if (remotePaths == null) {
-                        Log_OC.e(TAG, "Incorrect array for remote paths provided in upload intent");
-                        return Service.START_NOT_STICKY;
-                    }
-                    if (localPaths.length != remotePaths.length) {
-                        Log_OC.e(TAG, "Different number of remote paths and local paths!");
-                        return Service.START_NOT_STICKY;
-                    }
-
-                    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));
-                        if (files[i] == null) {
-                            Log_OC.e(TAG, "obtainNewOCFileToUpload() returned null for remotePaths[i]:" + remotePaths[i]
-                                    + " and localPaths[i]:" + localPaths[i]);
-                            return Service.START_NOT_STICKY;
-                        }
-
-                        mStorageManager.saveNewFile(files[i]);
-                        files[i] = mStorageManager.getFileByLocalPath(files[i].getStoragePath());
-                    }
-                }
-                // at this point variable "OCFile[] files" is loaded correctly.
-
-                String uploadKey = null;
-                UploadFileOperation newUpload = null;
-                try {
-                    for (int i = 0; i < files.length; i++) {
-                        newUpload = new UploadFileOperation(
-                                account,
-                                files[i],
-                                chunked,
-                                forceOverwrite,
-                                localAction,
-                                getApplicationContext()
-                        );
-                        if (isCreateRemoteFolder) {
-                            newUpload.setRemoteFolderToBeCreated();
-                        }
-                        newUpload.addDatatransferProgressListener(this);
-                        newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
-
-                        // Save upload in database
-                        OCUpload ocUpload = new OCUpload(files[i]);
-                        ocUpload.setAccountName(account.name);
-                        ocUpload.setForceOverwrite(forceOverwrite);
-                        ocUpload.setCreateRemoteFolder(isCreateRemoteFolder);
-                        ocUpload.setLocalAction(localAction);
-                        ocUpload.setUseWifiOnly(isUseWifiOnly);
-                        ocUpload.setWhileChargingOnly(isWhileChargingOnly);
-//                    ocUpload.setUploadTimestamp(uploadTimestamp);
-                        ocUpload.setUploadStatus(UploadStatus.UPLOAD_LATER);
-
-                        // storagePath inside upload is the temporary path. file
-                        // contains the correct path used as db reference.
-                        long id = mUploadsStorageManager.storeUpload(ocUpload);
-                        newUpload.setOCUploadId(id);
-
-                        Pair<String, String> putResult = mPendingUploads.putIfAbsent(
-                                account, files[i].getRemotePath(), newUpload, String.valueOf(id)
-                        );
-                        if (putResult != null) {
-                            uploadKey = putResult.first;
-                            requestedUploads.add(uploadKey);
-                        } else {
-                            mUploadsStorageManager.removeUpload(id);
-                        }
-                        // else, file already in the queue of uploads; don't repeat the request
-                    }
-
-                } catch (IllegalArgumentException e) {
-                    Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
-                    return START_NOT_STICKY;
-
-                } catch (IllegalStateException e) {
-                    Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
-                    return START_NOT_STICKY;
-
-                } catch (Exception e) {
-                    Log_OC.e(TAG, "Unexpected exception while processing upload intent", e);
-                    return START_NOT_STICKY;
-
-                }
-            } else {
-                if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_RETRY_UPLOAD) ) {
-                    Log_OC.e(TAG, "Not enough information provided in intent: no KEY_RETRY_UPLOAD_KEY");
-                    return START_NOT_STICKY;
-                }
-                OCUpload upload = intent.getParcelableExtra(KEY_RETRY_UPLOAD);
-
-                UploadFileOperation newUpload = new UploadFileOperation(
-                        account,
-                        upload.getOCFile(),
-                        chunked,
-                        upload.isForceOverwrite(),
-                        upload.getLocalAction(),
-                        getApplicationContext()
-                );
-                if (upload.isCreateRemoteFolder()) {
-                    newUpload.setRemoteFolderToBeCreated();
-                }
-                newUpload.addDatatransferProgressListener(this);
-                newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
-                newUpload.setOCUploadId(upload.getUploadId());
-
-                Pair<String, String> putResult = mPendingUploads.putIfAbsent(
-                        account, upload.getOCFile().getRemotePath(), newUpload, String.valueOf(upload.getUploadId())
-                );
-                if (putResult != null) {
-                    String uploadKey = putResult.first;
-                    requestedUploads.add(uploadKey);
-
-                    // Update upload in database
-                    upload.setUploadStatus(UploadStatus.UPLOAD_LATER);
-                    mUploadsStorageManager.updateUpload(upload);
-                }
-            }
-
-            if (requestedUploads.size() > 0) {
-                Message msg = mServiceHandler.obtainMessage();
-                msg.arg1 = startId;
-                msg.obj = requestedUploads;
-                mServiceHandler.sendMessage(msg);
-            }
-            return Service.START_NOT_STICKY;
-        }
-    }
-
-
-    @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
-    }
-
-    /**
-     * Provides a binder object that clients can use to perform operations on
-     * the queue of uploads, excepting the addition of new files.
-     *
-     * Implemented to perform cancellation, pause and resume of existing
-     * uploads.
-     */
-    @Override
-    public IBinder onBind(Intent arg0) {
-        return mBinder;
-    }
-
-    /**
-     * Called when ALL the bound clients were onbound.
-     */
-    @Override
-    public boolean onUnbind(Intent intent) {
-        ((FileUploaderBinder) mBinder).clearListeners();
-        return false; // not accepting rebinding (default behaviour)
-    }
-
-
-    /**
-     * Binder to let client components to perform operations on the queue of
-     * uploads.
-     *
-     * It provides by itself the available operations.
-     */
-    public class FileUploaderBinder extends Binder implements OnDatatransferProgressListener {
-
-        /**
-         * 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>();
-
-//        /**
-//         * Returns ongoing upload operation. May be null.
-//         */
-//        public UploadFileOperation getCurrentUploadOperation() {
-//            return mCurrentUpload;
-//        }
-
-        /**
-         * 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
-         */
-        public void cancel(Account account, OCFile file) {
-            // TODO: Remove this comment, when ending the implementation of reliable_uploads
-            // From FileUploader && FileUploaderService
-            Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
-            UploadFileOperation upload = removeResult.first;
-            if (upload != null) {
-                upload.cancel();
-            } else {
-                // updating current references (i.e., uploadStatus of current
-                // upload) is handled by updateDataseUploadResult() which is called
-                // after upload finishes. Following cancel call makes sure that is
-                // does finish right now.
-                if (mCurrentUpload != null && mCurrentUpload.isUploadInProgress() &&
-                        mCurrentUpload.getRemotePath().startsWith(file.getRemotePath()) &&
-                        account.name.equals(mCurrentAccount.name) ) {
-                    Log_OC.d(TAG, "Calling cancel for " + file.getRemotePath() + " during upload operation.");
-                    mCurrentUpload.cancel();
-//            } else if(mCancellationPossible.get()){
-//                Log_OC.d(TAG, "Calling cancel for " + file.getRemotePath() + " during preparing for upload.");
-//                mCancellationRequested.set(true);
-                } else {
-                    Log_OC.d(TAG, "Calling cancel for " + file.getRemotePath() + " while upload is pending.");
-                    // upload not in progress, but pending.
-                    // in this case we have to update the db here.
-                    //OCUpload upload = mPendingUploads.remove(buildRemoteName(account, file));
-                    OCUpload ocUpload = mUploadsStorageManager.getUploadByLocalPath(upload.getStoragePath())[0];
-                    ocUpload.setUploadStatus(UploadStatus.UPLOAD_CANCELLED);
-                    ocUpload.setLastResult(UploadResult.CANCELLED);
-                    // storagePath inside upload is the temporary path. file
-                    // contains the correct path used as db reference.
-                    ocUpload.getOCFile().setStoragePath(file.getStoragePath());
-                    mUploadsStorageManager.updateUploadStatus(ocUpload);
-                }
-            }
-        }
-
-        /**
-         * 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
-            cancelUploadsForAccount(account);
-        }
-
-        // TODO: Review: Method from FileUploadService with some changes because the merge with FileUploader
-        public void remove(Account account, OCFile file) {
-            Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
-            UploadFileOperation upload = removeResult.first;
-            //OCUpload upload = mPendingUploads.remove(buildRemoteName(account, file));
-            if(upload == null) {
-                Log_OC.e(TAG, "Could not delete upload " + file + " from mPendingUploads.");
-            }
-            int d = mUploadsStorageManager.removeUpload(upload.getStoragePath());
-            if(d == 0) {
-                Log_OC.e(TAG, "Could not delete upload "+ file.getStoragePath() +" from database.");
-            }
-        }
-
-        public void remove(OCUpload upload) {
-            int d = mUploadsStorageManager.removeUpload(upload.getUploadId());
-            if(d == 0) {
-                Log_OC.e(TAG, "Could not delete upload "+ upload.getRemotePath() +" from database.");
-            }
-        }
-
-        // TODO: Review: Method from FileUploadService with some changes because the merge with FileUploader
-        // TODO Complete operation to retry the upload
-        /**
-         * Puts upload in upload list and tell FileUploadService to upload items in list.
-         */
-        public void retry(Account account, OCUpload upload) {
-//            String uploadKey = buildRemoteName(account, upload.getOCFile());
-//            mPendingUploads.put(uploadKey, upload);
-            FileUploadService.retry(getApplicationContext(), account, upload);
-        }
-
-        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
-         *
-         * If 'file' is a directory, returns 'true' if some of its descendant
-         * files is uploading or waiting to upload.
-         *
-         * Warning: If remote file exists and !forceOverwrite the original file
-         * is being returned here. That is, it seems as if the original file is
-         * being updated when actually a new file is being uploaded.
-         *
-         * @param account Owncloud account where the remote file will be stored.
-         * @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;
-            return (mPendingUploads.contains(account, file.getRemotePath()));
-            // Commented code from FileUploadService
-//            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));
-//                }
-//            }
-        }
-
-        /**
-         * Adds a listener interested in the progress of the upload 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.
-         */
-        public void addDatatransferProgressListener(OnDatatransferProgressListener listener, Account account,
-                                                    OCFile file, long uploadId) {
-            if (account == null || file == null || listener == null)
-                return;
-            String targetKey = buildRemoteName(account, file, uploadId);
-            mBoundListeners.put(targetKey, listener);
-        }
-
-        /**
-         * Removes a listener interested in the progress of the upload 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.
-         */
-        public void removeDatatransferProgressListener(OnDatatransferProgressListener listener, Account account,
-                                                       OCFile file, long uploadId) {
-            if (account == null || file == null || listener == null)
-                return;
-            String targetKey = buildRemoteName(account, file, uploadId);
-            if (mBoundListeners.get(targetKey) == listener) {
-                mBoundListeners.remove(targetKey);
-            }
-        }
-
-
-        // TODO: Review: Method from FileUploadService with some changes because the merge with FileUploader
-        @Override
-        public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
-                                       String fileName) {
-
-            OCFile uploadFileKey = mCurrentUpload.getFile();
-            if(mCurrentUpload.wasRenamed()){
-                uploadFileKey = mCurrentUpload.getOldFile();
-            }
-            String key = buildRemoteName(mCurrentUpload.getAccount(), uploadFileKey,
-                    mCurrentUpload.getOCUploadId());
-            OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
-            if (boundListener != null) {
-                boundListener.onTransferProgress(progressRate, totalTransferredSoFar,
-                        totalToTransfer, fileName);
-            }
-//
-//            Set<Entry<String, OCUpload>> uploads = mPendingUploads.entrySet();
-//            UploadFileOperation currentUpload = mCurrentUpload;
-//            if (currentUpload == null) {
-//                Log_OC.e(TAG, "Found no current upload with remote path " + localFileName + ". Ignore.");
-//                return;
-//            }
-//            String key = buildRemoteName(currentUpload.getAccount(), currentUpload.getFile());
-//            OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
-//            if (boundListener != null) {
-//                boundListener.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, localFileName);
-//            }
-        }
-
-        /**
-         * 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
-         */
-        private String buildRemoteName(Account account, OCFile file, long uploadId) {
-            String suffix = String.valueOf(uploadId);
-            if (uploadId != -1) {
-                suffix = "";
-            }
-            return account.name + file.getRemotePath() + suffix;
-        }
-
-    }
-
-    // TODO: Remove this comment: Class totally replaced by FileUploader ServiceHandler
-    // TODO: Review merge modifications
-    /**
-     * Upload worker. Performs the pending uploads in the order they were
-     * requested.
-     *
-     * Created with the Looper of a new thread, started in
-     * {@link FileUploadService#onCreate()}.
-     */
-    private static class ServiceHandler extends Handler {
-        // don't make it a final class, and don't remove the static ; lint will
-        // warn about a possible memory leak
-        FileUploadService mService;
-
-        public ServiceHandler(Looper looper, FileUploadService service) {
-            super(looper);
-            if (service == null)
-                throw new IllegalArgumentException("Received invalid NULL in parameter 'service'");
-            mService = service;
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            @SuppressWarnings("unchecked")
-            AbstractList<String> requestedUploads = (AbstractList<String>) msg.obj;
-            if (msg.obj != null) {
-                Iterator<String> it = requestedUploads.iterator();
-                while (it.hasNext()) {
-                    mService.uploadFile(it.next());
-                }
-            }
-            Log_OC.d(TAG, "Stopping command after id " + msg.arg1);
-            mService.stopSelf(msg.arg1);
-        }
-    }
-
-    // TODO: Method from FileUploader
-    /**
-     * Core upload method: sends the file(s) to upload
-     *
-     * @param uploadKey     Key to access the upload to perform, contained in mPendingUploads
-     */
-    public void uploadFile(String uploadKey) {
-
-        mCurrentUpload = mPendingUploads.get(uploadKey);
-
-        if (mCurrentUpload != null) {
-            // Detect if the account exists
-            if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
-                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().name + " exists");
-
-                mCurrentUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
-                mCurrentUpload.addDatatransferProgressListener(this);
-
-                notifyUploadStart(mCurrentUpload);
-
-                RemoteOperationResult uploadResult = null, grantResult;
-
-                try {
-                    /// prepare client object to send the request to the ownCloud server
-                    if (mCurrentAccount == null || !mCurrentAccount.equals(mCurrentUpload.getAccount())) {
-                        mCurrentAccount = mCurrentUpload.getAccount();
-                        mStorageManager = new FileDataStorageManager(
-                                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(mCurrentAccount, this);
-                    mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
-                            getClientFor(ocAccount, this);
-
-
-                    /// 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;
-                    grantResult = grantFolderExistence(remoteParentPath);
-
-                    /// perform the upload
-                    if (grantResult.isSuccess()) {
-                        /*OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
-                        mCurrentUpload.getFile().setParentId(parent.getFileId());*/
-                        uploadResult = mCurrentUpload.execute(mUploadClient);
-                        if (uploadResult.isSuccess()) {
-                            saveUploadedFile();
-
-                        } else if (uploadResult.getCode() == ResultCode.SYNC_CONFLICT) {
-                            mStorageManager.saveConflict(mCurrentUpload.getFile(),
-                                    mCurrentUpload.getFile().getEtagInConflict());
-                        }
-                    } else {
-                        uploadResult = grantResult;
-                    }
-
-                } catch (Exception e) {
-                    Log_OC.e(TAG, "Error uploading", e);
-                    uploadResult = new RemoteOperationResult(e);
-
-                } finally {
-                    Pair<UploadFileOperation, String> removeResult;
-                    if (mCurrentUpload.wasRenamed()) {
-                        removeResult = mPendingUploads.removePayload(
-                                mCurrentAccount,
-                                mCurrentUpload.getOldFile().getRemotePath()
-                        );
-                        mUploadsStorageManager.updateFileIdUpload(mCurrentUpload.getOCUploadId(),
-                                mCurrentUpload.getFile().getFileId());
-                    } else {
-                        removeResult = mPendingUploads.removePayload(
-                                mCurrentAccount,
-                                mCurrentUpload.getRemotePath()
-                        );
-                    }
-
-                    /// notify result
-                    notifyUploadResult(mCurrentUpload, uploadResult);
-
-                    sendBroadcastUploadFinished(mCurrentUpload, uploadResult, removeResult.second);
-                }
-
-            } else {
-                // Cancel the transfer
-                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() +
-                        " doesn't exist");
-                cancelUploadsForAccount(mCurrentUpload.getAccount());
-
-            }
-        }
-
-    }
-
-    // TODO: Replaced by uploadFile(String uploadKey)
-    /**
-     * Core upload method: sends the file(s) to upload. This function blocks
-     * until upload succeeded or failed.
-     *
-     * Before uploading starts mCurrentUpload is set.
-     *
-     * @param OCUpload Key to access the upload to perform, contained in
-     *            mPendingUploads
-     * @return RemoteOperationResult of upload operation.
-     */
-//    private RemoteOperationResult uploadFile(OCUpload OCUpload) {
-//
-//        if (mCurrentUpload != null) {
-//            Log_OC.e(TAG,
-//                    "mCurrentUpload != null. Meaning there is another upload in progress, cannot start a new one. Fix that!");
-//            return new RemoteOperationResult(new IllegalStateException("mCurrentUpload != null when calling uploadFile()"));
-//        }
-//
-//        AccountManager aMgr = AccountManager.get(this);
-//        Account account = OCUpload.getAccount(getApplicationContext());
-//        String version = aMgr.getUserData(account, Constants.KEY_OC_VERSION);
-//        OwnCloudVersion ocv = new OwnCloudVersion(version);
-//
-//        boolean chunked = FileUploadService.chunkedUploadIsSupported(ocv);
-//        String uploadKey = null;
-//
-//        uploadKey = buildRemoteName(account, OCUpload.getRemotePath());
-//        OCFile file = OCUpload.getOCFile();
-//        Log_OC.d(TAG, "mCurrentUpload = new UploadFileOperation");
-//        mCurrentUpload = new UploadFileOperation(account, file, chunked, OCUpload.isForceOverwrite(),
-//                OCUpload.getLocalAction(), getApplicationContext());
-//        if (OCUpload.isCreateRemoteFolder()) {
-//            mCurrentUpload.setRemoteFolderToBeCreated();
-//        }
-//        mCurrentUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
-//        mCurrentUpload.addDatatransferProgressListener(this);
-//
-//        mCancellationRequested.set(false);
-//        mCancellationPossible.set(true);
-//        notifyUploadStart(mCurrentUpload);
-//
-//        RemoteOperationResult uploadResult = null, grantResult = null;
-//        try {
-//            // prepare client object to send requests to the ownCloud
-//            // server
-//            if (mUploadClient == null || !mCurrentAccount.equals(mCurrentUpload.getAccount())) {
-//                mCurrentAccount = mCurrentUpload.getAccount();
-//                mStorageManager = new FileDataStorageManager(mCurrentAccount, getContentResolver());
-//                OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
-//                mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, this);
-//            }
-//
-//            // 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;
-//            //TODO this might take a moment and should thus be cancelable, for now: cancel afterwards.
-//            grantResult = grantFolderExistence(mCurrentUpload, remoteParentPath);
-//
-//            if(mCancellationRequested.get()) {
-//                throw new OperationCancelledException();
-//            }
-//            mCancellationPossible.set(false);
-//
-//            // perform the upload
-//            if (grantResult.isSuccess()) {
-//                OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
-//                mCurrentUpload.getFile().setParentId(parent.getFileId());
-//                // inside this call the remote path may be changed (if remote
-//                // file exists and !forceOverwrite) in this case the map from
-//                // mPendingUploads is wrong. This results in an upload
-//                // indication in the GUI showing that the original file is being
-//                // uploaded (instead that a new one is created)
-//                uploadResult = mCurrentUpload.execute(mUploadClient);
-//                if (uploadResult.isSuccess()) {
-//                    saveUploadedFile(mCurrentUpload);
-//                }
-//            } else {
-//                uploadResult = grantResult;
-//            }
-//
-//        } catch (AccountsException e) {
-//            Log_OC.e(TAG, "Error while trying to get autorization for " + mCurrentAccount.name, e);
-//            uploadResult = new RemoteOperationResult(e);
-//
-//        } catch (IOException e) {
-//            Log_OC.e(TAG, "Error while trying to get autorization for " + mCurrentAccount.name, e);
-//            uploadResult = new RemoteOperationResult(e);
-//
-//        } catch (OperationCancelledException e) {
-//            uploadResult = new RemoteOperationResult(e);
-//        } finally {
-//            Log_OC.d(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
-//                mUploadClient = null;
-//            }
-//        }
-//        return uploadResult;
-//    }
-
-    /**
-     * 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.
-     *
-     *  @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.
-     */
-    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()) {
-            SyncOperation syncOp = new CreateFolderOperation( pathToGrant, true);
-            result = syncOp.execute(mUploadClient, mStorageManager);
-        }
-        if (result.isSuccess()) {
-            OCFile parentDir = mStorageManager.getFileByPath(pathToGrant);
-            if (parentDir == null) {
-                parentDir = createLocalFolder(pathToGrant);
-            }
-            if (parentDir != null) {
-                result = new RemoteOperationResult(ResultCode.OK);
-            } else {
-                result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
-            }
-        }
-        return result;
-    }
-
-    private OCFile createLocalFolder(String remotePath) {
-        String parentPath = new File(remotePath).getParent();
-        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ?
-                parentPath : parentPath + OCFile.PATH_SEPARATOR;
-        OCFile parent = mStorageManager.getFileByPath(parentPath);
-        if (parent == null) {
-            parent = createLocalFolder(parentPath);
-        }
-        if (parent != null) {
-            OCFile createdFolder = new OCFile(remotePath);
-            createdFolder.setMimetype("DIR");
-            createdFolder.setParentId(parent.getFileId());
-            mStorageManager.saveFile(createdFolder);
-            return createdFolder;
-        }
-        return null;
-    }
-
-
-    /**
-     * Saves a OC File after a successful upload.
-     *
-     * A PROPFIND is necessary to keep the props in the local database
-     * synchronized with the server, specially the modification time and Etag
-     * (where available)
-     *
-     * TODO move into UploadFileOperation
-     */
-    private void saveUploadedFile() {
-        OCFile file = mCurrentUpload.getFile();
-        if (file.fileExists()) {
-            file = mStorageManager.getFileById(file.getFileId());
-        }
-        long syncDate = System.currentTimeMillis();
-        file.setLastSyncDateForData(syncDate);
-
-        // new PROPFIND to keep data consistent with server
-        // in theory, should return the same we already have
-        ReadRemoteFileOperation operation =
-                new ReadRemoteFileOperation(mCurrentUpload.getRemotePath());
-        RemoteOperationResult result = operation.execute(mUploadClient);
-        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
-        // maybe all this method
-        if (mCurrentUpload.wasRenamed()) {
-            OCFile oldFile = mCurrentUpload.getOldFile();
-            if (oldFile.fileExists()) {
-                oldFile.setStoragePath(null);
-                mStorageManager.saveFile(oldFile);
-                mStorageManager.saveConflict(oldFile, null);
-
-            } // else: it was just an automatic renaming due to a name
-            // coincidence; nothing else is needed, the storagePath is right
-            // in the instance returned by mCurrentUpload.getFile()
-        }
-        file.setNeedsUpdateThumbnail(true);
-        mStorageManager.saveFile(file);
-        mStorageManager.saveConflict(file, null);
-
-        mStorageManager.triggerMediaScan(file.getStoragePath());
-
-    }
-
-    private void updateOCFile(OCFile file, RemoteFile remoteFile) {
-        file.setCreationTimestamp(remoteFile.getCreationTimestamp());
-        file.setFileLength(remoteFile.getLength());
-        file.setMimetype(remoteFile.getMimeType());
-        file.setModificationTimestamp(remoteFile.getModifiedTimestamp());
-        file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp());
-        file.setEtag(remoteFile.getEtag());
-        file.setRemoteId(remoteFile.getRemoteId());
-    }
-
-    private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType) {
-
-        // MIME type
-        if (mimeType == null || mimeType.length() <= 0) {
-            try {
-                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);
-            }
-        }
-        if (mimeType == null) {
-            mimeType = "application/octet-stream";
-        }
-
-        if (isPdfFileFromContentProviderWithoutExtension(localPath, mimeType)){
-            remotePath += FILE_EXTENSION_PDF;
-        }
-
-        OCFile newFile = new OCFile(remotePath);
-        newFile.setStoragePath(localPath);
-        newFile.setLastSyncDateForProperties(0);
-        newFile.setLastSyncDateForData(0);
-
-        // size
-        if (localPath != null && localPath.length() > 0) {
-            File localFile = new File(localPath);
-            newFile.setFileLength(localFile.length());
-            newFile.setLastSyncDateForData(localFile.lastModified());
-        } // don't worry about not assigning size, the problems with localPath
-        // are checked when the UploadFileOperation instance is created
-
-
-        newFile.setMimetype(mimeType);
-
-        return newFile;
-    }
-
-
-    /**
-     * Creates a status notification to show the upload progress
-     *
-     * @param upload Upload operation starting.
-     */
-    private void notifyUploadStart(UploadFileOperation upload) {
-        // / create status notification with a progress bar
-        mLastPercent = 0;
-        mNotificationBuilder =
-                NotificationBuilderWithProgressBar.newNotificationBuilderWithProgressBar(this);
-        mNotificationBuilder
-                .setOngoing(true)
-                .setSmallIcon(R.drawable.notification_icon)
-                .setTicker(getString(R.string.uploader_upload_in_progress_ticker))
-                .setContentTitle(getString(R.string.uploader_upload_in_progress_ticker))
-                .setProgress(100, 0, false)
-                .setContentText(
-                        String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName()));
-
-        /// includes a pending intent in the notification showing the details
-        Intent showUploadListIntent = new Intent(this, UploadListActivity.class);
-        showUploadListIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile());
-        showUploadListIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
-        showUploadListIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(this, (int) System.currentTimeMillis(),
-                showUploadListIntent, 0));
-
-        // TODO: Review Old behaviour in FileUploader
-        /// includes a pending intent in the notification showing the details view of the file
-//        Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class);
-//        showDetailsIntent.putExtra(FileActivity.EXTRA_FILE,  (Parcelable) upload.getFile());
-//        showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
-//        showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-//        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-//                this, (int) System.currentTimeMillis(), showDetailsIntent, 0
-//        ));
-
-        mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
-
-        sendBroadcastUploadStarted(mCurrentUpload);
-    }
-
-
-
-    /**
-     * Callback method to update the progress bar in the status notification
-     */
-    @Override
-    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);
-            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());
-        }
-        mLastPercent = percent;
-    }
-
-    /**
-     * Updates the status notification with the result of an upload operation.
-     *
-     * @param uploadResult  Result of the upload operation.
-     * @param upload        Finished upload operation
-     */
-    private void notifyUploadResult(UploadFileOperation upload,
-                                    RemoteOperationResult uploadResult) {
-        Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
-        // / cancelled operation or success -> silent removal of progress
-        // notification
-        mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
-
-        // Show the result: success or fail notification
-        if (!uploadResult.isCancelled()) {
-            int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker
-                    : R.string.uploader_upload_failed_ticker;
-
-            String content; // = null;
-
-            // check credentials error
-            boolean needsToUpdateCredentials = (
-                    uploadResult.getCode() == ResultCode.UNAUTHORIZED ||
-                            uploadResult.isIdPRedirection()
-            );
-            tickerId = (needsToUpdateCredentials) ?
-                    R.string.uploader_upload_failed_credentials_error : tickerId;
-
-            mNotificationBuilder
-                    .setTicker(getString(tickerId))
-                    .setContentTitle(getString(tickerId))
-                    .setAutoCancel(true)
-                    .setOngoing(false)
-                    .setProgress(0, 0, false);
-
-            content = ErrorMessageAdapter.getErrorCauseMessage(
-                    uploadResult, upload, getResources()
-            );
-
-            if (needsToUpdateCredentials) {
-                // let the user update credentials with one click
-                Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
-                updateAccountCredentials.putExtra(
-                        AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount()
-                );
-                updateAccountCredentials.putExtra(
-                        AuthenticatorActivity.EXTRA_ACTION,
-                        AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
-                updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-                updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
-                mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-                        this,
-                        (int) System.currentTimeMillis(),
-                        updateAccountCredentials,
-                        PendingIntent.FLAG_ONE_SHOT));
-
-                mUploadClient = null;
-                // grant that future retries on the same account will get the fresh credentials
-
-            }else {
-                mNotificationBuilder.setContentText(content);
- //Changes for compilation
-//                if (upload.isInstant()) {
-//                    DbHandler db = null;
-//                    try {
-//                        db = new DbHandler(this.getBaseContext());
-//                        String message = uploadResult.getLogMessage() + " errorCode: " +
-//                                uploadResult.getCode();
-//                        Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
-//                        if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
-//                            //message = getString(R.string.failed_upload_quota_exceeded_text);
-//                            if (db.updateFileState(
-//                                    upload.getOriginalStoragePath(),
-//                                    DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
-//                                    message) == 0) {
-//                                db.putFileForLater(
-//                                        upload.getOriginalStoragePath(),
-//                                        upload.getAccount().name,
-//                                        message
-//                                );
-//                            }
-//                        }
-//                    } finally {
-//                        if (db != null) {
-//                            db.close();
-//                        }
-//                    }
-//                }
-            }
-
-            updateDatabaseUploadResult(uploadResult, mCurrentUpload);
-
-            if(!uploadResult.isSuccess()){
-                //in case of failure, do not show details file view (because there is no file!)
-                Intent showUploadListIntent = new Intent(this, UploadListActivity.class);
-                showUploadListIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile());
-                showUploadListIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
-                showUploadListIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                mNotificationBuilder.setContentIntent(PendingIntent.getActivity(this, (int) System.currentTimeMillis(),
-                        showUploadListIntent, 0));
-            }
-
-            mNotificationBuilder.setContentText(content);
-            mNotificationManager.notify(tickerId, mNotificationBuilder.build());
-
-            if (uploadResult.isSuccess()) {
-//Changes for compilation
-//                DbHandler db = new DbHandler(this.getBaseContext());
-//                db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
-//                db.close();
-                mPendingUploads.remove(upload.getAccount(), upload.getFile().getRemotePath());
-                //updateDatabaseUploadResult(uploadResult, mCurrentUpload);
-                // remove success notification, with a delay of 2 seconds
-                NotificationDelayer.cancelWithDelay(mNotificationManager, R.string.uploader_upload_succeeded_ticker,
-                        2000);
-            }
-        }
-    }
-
-    /**
-     * Updates the persistent upload database with upload result.
-     */
-    private void updateDatabaseUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
-        // result: success or fail notification
-        Log_OC.d(TAG, "updateDataseUploadResult uploadResult: " + uploadResult + " upload: " + upload);
-        if (uploadResult.isCancelled()) {
-            mUploadsStorageManager.updateUploadStatus(
-                    upload.getOCUploadId(),
-                    UploadStatus.UPLOAD_CANCELLED,
-                    UploadResult.CANCELLED
-            );
-        } else {
-
-            if (uploadResult.isSuccess()) {
-                mUploadsStorageManager.updateUploadStatus(
-                        upload.getOCUploadId(),
-                        UploadStatus.UPLOAD_SUCCEEDED,
-                        UploadResult.UPLOADED
-                );
-            } else {
-                // TODO: Disable for testing of menu actions in uploads view
-                if (shouldRetryFailedUpload(uploadResult)) {
-                    mUploadsStorageManager.updateUploadStatus(
-                            upload.getOCUploadId(), UploadStatus.UPLOAD_FAILED_RETRY,
-                            UploadResult.fromOperationResult(uploadResult));
-                } else {
-                    mUploadsStorageManager.updateUploadStatus(upload.getOCUploadId(),
-                            UploadsStorageManager.UploadStatus.UPLOAD_FAILED_GIVE_UP,
-                            UploadResult.fromOperationResult(uploadResult));
-                }
-            }
-        }
-    }
-
-    // TODO: Disable for testing of menu actions in uploads view
-
-    /**
-     * Determines whether with given uploadResult the upload should be retried later.
-     * @param uploadResult
-     * @return true if upload should be retried later, false if is should be abandoned.
-     */
-    private boolean shouldRetryFailedUpload(RemoteOperationResult uploadResult) {
-        if (uploadResult.isSuccess()) {
-            return false;
-        }
-        switch (uploadResult.getCode()) {
-            case HOST_NOT_AVAILABLE:
-            case NO_NETWORK_CONNECTION:
-            case TIMEOUT:
-            case WRONG_CONNECTION: // SocketException
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Updates the persistent upload database that upload is in progress.
-     */
-    private void updateDatabaseUploadStart(UploadFileOperation upload) {
-        mUploadsStorageManager.updateUploadStatus(
-                upload.getOCUploadId(),
-                UploadStatus.UPLOAD_IN_PROGRESS,
-                UploadResult.UNKNOWN
-        );
-    }
-
-    /**
-     * Sends a broadcast in order to the interested activities can update their
-     * view
-     *
-     * @param upload                    Finished upload operation
-     */
-    private void sendBroadcastUploadStarted(
-            UploadFileOperation upload) {
-
-        Intent start = new Intent(getUploadStartMessage());
-        start.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
-        start.putExtra(EXTRA_OLD_FILE_PATH, upload.getOriginalStoragePath());
-        start.putExtra(ACCOUNT_NAME, upload.getAccount().name);
-
-        updateDatabaseUploadStart(mCurrentUpload);
-
-        sendStickyBroadcast(start);
-    }
-
-    /**
-     * Sends a broadcast in order to the interested activities can update their
-     * view
-     *
-     * @param upload                    Finished upload operation
-     * @param uploadResult              Result of the upload operation
-     * @param unlinkedFromRemotePath    Path in the uploads tree where the upload was unlinked from
-     */
-    private void sendBroadcastUploadFinished(
-            UploadFileOperation upload,
-            RemoteOperationResult uploadResult,
-            String unlinkedFromRemotePath) {
-
-        Intent end = new Intent(getUploadFinishMessage());
-        end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
-        // path, after
-        // possible
-        // automatic
-        // renaming
-        if (upload.wasRenamed()) {
-            end.putExtra(EXTRA_OLD_REMOTE_PATH, upload.getOldFile().getRemotePath());
-        }
-        end.putExtra(EXTRA_OLD_FILE_PATH, upload.getOriginalStoragePath());
-        end.putExtra(ACCOUNT_NAME, upload.getAccount().name);
-        end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult.isSuccess());
-        if (unlinkedFromRemotePath != null) {
-            end.putExtra(EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath);
-        }
-
-        updateDatabaseUploadResult(uploadResult, mCurrentUpload);
-
-        sendStickyBroadcast(end);
-    }
-
-
-    // TODO: Remove. Replace by sendBroadcastUploadFinished(UploadFileOperation, RemoteOperationResult, String)
-//    /**
-//     * Sends a broadcast in order to the interested activities can update their
-//     * view
-//     * @param uploadResult Result of the upload operation
-//     * @param upload Finished upload operation
-//     */
-//    private void sendFinalBroadcast(RemoteOperationResult uploadResult, UploadFileOperation upload) {
-//        Intent end = new Intent(getUploadFinishMessage());
-//        end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
-//        // path, after
-//        // possible
-//        // automatic
-//        // renaming
-//        if (upload.wasRenamed()) {
-//            end.putExtra(EXTRA_OLD_REMOTE_PATH, upload.getOldFile().getRemotePath());
-//        }
-//        end.putExtra(EXTRA_OLD_FILE_PATH, upload.getOriginalStoragePath());
-//        end.putExtra(ACCOUNT_NAME, upload.getAccount().name);
-//        end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult.isSuccess());
-//        sendStickyBroadcast(end);
-//    }
-
-    /**
-     * Checks if content provider, using the content:// scheme, returns a file with mime-type
-     * 'application/pdf' but file has not extension
-     * @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) {
-        return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) &&
-                mimeType.equals(MIME_TYPE_PDF) &&
-                !localPath.endsWith(FILE_EXTENSION_PDF);
-    }
-
-    /**
-     * Remove uploads of an account
-     *
-     * @param account       Downloads account to remove
-     */
-    private void cancelUploadsForAccount(Account account){
-        // Cancel pending uploads
-        mPendingUploads.remove(account);
-    }
-
-//    TODO: Remove
-//    /**
-//     * Remove uploads of an account
-//     * @param accountName       Name of an OC account
-//     */
-//    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);
-//                }
-//            }
-//        }
-//    }
-
-
-    // TODO: onHandleIntent not used in the new FileUploadService
-    // TODO: Remove when clean code
-    /**
-     * The IntentService calls this method from the default worker thread with
-     * the intent that started the service. When this method returns,
-     * IntentService stops the service, as appropriate.
-     *
-     * Note: We use an IntentService here. It does not provide simultaneous
-     * requests, but instead internally queues them and gets them to this
-     * onHandleIntent method one after another. This makes implementation less
-     * error-prone but prevents files to be added to list while another upload
-     * is active. If everything else works fine, fixing this should be a TODO.
-     *
-     * 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
-     * this method. This ensures the service will keep on working although the
-     * caller activity goes away.
-     *
-     * First, onHandleIntent() stores all information associated with the upload
-     * in a {@link OCUpload} which is stored persistently using
-     * {@link UploadsStorageManager}. Then, the oldest, pending upload from
-     * {@link UploadsStorageManager} is taken and upload is started.
-     * @param intentStartId
-     */
-//
-//    protected void onHandleIntent(Intent intent, int intentStartId) {
-//        Log_OC.d(TAG, "onHandleIntent start");
-//        //Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - before adding new uploads.");
-//        Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.toString() + " - before adding new uploads.");
-//        if (intent == null || intent.hasExtra(KEY_RETRY)) {
-//            Log_OC.d(TAG, "Received null intent.");
-//            // service was restarted by OS or connectivity change was detected or
-//            // retry of pending upload was requested.
-//            // ==> First check persistent uploads, then perform upload.
-//            int countAddedEntries = 0;
-//            OCUpload[] list = mUploadsStorageManager.getPendingUploads();
-//            for (OCUpload OCUpload : list) {
-//                Log_OC.d(TAG, "Retrieved from DB: " + OCUpload.toFormattedString());
-//
-//                String uploadKey = buildRemoteName(OCUpload);
-//                OCUpload previous = mPendingUploads.putIfAbsent(uploadKey, OCUpload);
-//                if(previous == null) {
-//                    Log_OC.d(TAG, "mPendingUploads added: " + OCUpload.toFormattedString());
-//                    countAddedEntries++;
-//                } else {
-//                    //already pending. ignore.
-//                }
-//            }
-//            Log_OC.d(TAG, "added " + countAddedEntries
-//                    + " entrie(s) to mPendingUploads (this should be 0 except for the first time).");
-//            // null intent is received when charging or wifi state changes.
-//            // fake a mUploadsStorageManager change event, so that GUI can update the reason for
-//            // LATER status of uploads.
-//            mUploadsStorageManager.notifyObserversNow();
-//        } else {
-//            Log_OC.d(TAG, "Receive upload intent.");
-//            UploadQuantity uploadType = (UploadQuantity) intent.getSerializableExtra(KEY_UPLOAD_TYPE);
-//            if (uploadType == null) {
-//                Log_OC.e(TAG, "Incorrect or no upload type provided");
-//                return;
-//            }
-//
-//            Account account = intent.getParcelableExtra(KEY_ACCOUNT);
-//            if (!AccountUtils.exists(account, getApplicationContext())) {
-//                Log_OC.e(TAG, "KEY_ACCOUNT no set or provided KEY_ACCOUNT does not exist");
-//                return;
-//            }
-//            mStorageManager = new FileDataStorageManager(account, getContentResolver());
-//
-//            OCFile[] files = null;
-//            // if KEY_FILE given, use it
-//            if (intent.hasExtra(KEY_FILE)) {
-//                if (uploadType == UploadQuantity.UPLOAD_SINGLE_FILE) {
-//                    files = new OCFile[] { intent.getParcelableExtra(KEY_FILE) };
-//                } else {
-//                    files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE);
-//                }
-//
-//            } else { // else use KEY_LOCAL_FILE and KEY_REMOTE_FILE
-//
-//                if (!intent.hasExtra(KEY_LOCAL_FILE) || !intent.hasExtra(KEY_REMOTE_FILE)) {
-//                    Log_OC.e(TAG, "Not enough information provided in intent");
-//                    return;
-//                }
-//
-//                String[] localPaths;
-//                String[] remotePaths;
-//                String[] mimeTypes;
-//                if (uploadType == UploadQuantity.UPLOAD_SINGLE_FILE) {
-//                    localPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
-//                    remotePaths = new String[] { intent.getStringExtra(KEY_REMOTE_FILE) };
-//                    mimeTypes = new String[] { intent.getStringExtra(KEY_MIME_TYPE) };
-//                } else {
-//                    localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
-//                    remotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
-//                    mimeTypes = intent.getStringArrayExtra(KEY_MIME_TYPE);
-//                }
-//                if (localPaths.length != remotePaths.length) {
-//                    Log_OC.e(TAG, "Different number of remote paths and local paths!");
-//                    return;
-//                }
-//
-//                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));
-//                    if (files[i] == null) {
-//                        Log_OC.e(TAG, "obtainNewOCFileToUpload() returned null for remotePaths[i]:" + remotePaths[i]
-//                                + " and localPaths[i]:" + localPaths[i]);
-//                        return;
-//                    }
-//                    mStorageManager.saveFile(files[i]);
-//                    files[i] = mStorageManager.getFileByLocalPath(files[i].getStoragePath());
-//                }
-//            }
-//
-//            // at this point variable "OCFile[] files" is loaded correctly.
-//
-//            boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
-//            boolean isCreateRemoteFolder = intent.getBooleanExtra(KEY_CREATE_REMOTE_FOLDER, false);
-//            boolean isUseWifiOnly = intent.getBooleanExtra(KEY_WIFI_ONLY, true);
-//            boolean isWhileChargingOnly = intent.getBooleanExtra(KEY_WHILE_CHARGING_ONLY, false);
-//            long uploadTimestamp = intent.getLongExtra(KEY_UPLOAD_TIMESTAMP, -1);
-//
-//            LocalBehaviour localAction = (LocalBehaviour) intent.getSerializableExtra(KEY_LOCAL_BEHAVIOUR);
-//            if (localAction == null)
-//                localAction = LocalBehaviour.LOCAL_BEHAVIOUR_COPY;
-//
-//            // save always persistently path of upload, so it can be retried if
-//            // failed.
-//            for (int i = 0; i < files.length; i++) {
-//                OCUpload upload = new OCUpload(files[i]);
-//                upload.setAccountName(account.name);
-//                upload.setForceOverwrite(forceOverwrite);
-//                upload.setCreateRemoteFolder(isCreateRemoteFolder);
-//                upload.setLocalAction(localAction);
-//                upload.setUseWifiOnly(isUseWifiOnly);
-//                upload.setWhileChargingOnly(isWhileChargingOnly);
-//                upload.setUploadTimestamp(uploadTimestamp);
-//                upload.setUploadStatus(UploadStatus.UPLOAD_LATER);
-//
-//                String uploadKey = buildRemoteName(upload);
-//                OCUpload previous = mPendingUploads.putIfAbsent(uploadKey, upload);
-//
-//                if(previous == null)
-//                {
-//                    Log_OC.d(TAG, "mPendingUploads added: " + upload.toFormattedString());
-//
-//                    // if upload was not queued before, we can add it to
-//                    // database because the user wants the file to be uploaded.
-//                    // however, it can happened that the user uploaded the same
-//                    // file before in which case there is an old db entry.
-//                    // delete that to be sure we have the latest one.
-//                    if(mUploadsStorageManager.removeUpload(upload.getLocalPath())>0) {
-//                        Log_OC.w(TAG, "There was an old DB entry " + upload.getLocalPath()
-//                                + " which had to be removed in order to add new one.");
-//                    }
-//                    boolean success = mUploadsStorageManager.storeUpload(upload);
-//                    if(!success) {
-//                        Log_OC.e(TAG, "Could not add upload " + upload.getLocalPath()
-//                                + " to database. This should not happen.");
-//                    }
-//                } else {
-//                    Log_OC.w(TAG, "FileUploadService got upload intent for file which is already queued: "
-//                            + upload.getRemotePath());
-//                    // upload already pending. ignore.
-//                }
-//            }
-//        }
-//        // at this point mPendingUploads is filled.
-//
-//
-//
-//        Iterator<String> it;
-//        if (intent != null && intent.getStringExtra(KEY_RETRY_REMOTE_PATH) != null) {
-//            ArrayList<String> list = new ArrayList<String>(1);
-//            String remotePath = intent.getStringExtra(KEY_RETRY_REMOTE_PATH);
-//            list.add(remotePath);
-//            it = list.iterator();
-//            // update db status for upload
-//            OCUpload OCUpload = mPendingUploads.get(remotePath);
-//            OCUpload.setUploadStatus(UploadStatus.UPLOAD_LATER);
-//            OCUpload.setLastResult(null);
-//            mUploadsStorageManager.updateUploadStatus(OCUpload);
-//
-//            Log_OC.d(TAG, "Start uploading " + remotePath);
-//        } else {
-//            it = mPendingUploads.keySet().iterator();
-//        }
-//        if (it.hasNext()) {
-//            while (it.hasNext()) {
-//                String upload = it.next();
-//                OCUpload OCUpload = mPendingUploads.get(upload);
-//
-//                if (OCUpload == null) {
-//                    Log_OC.e(TAG, "Cannot upload null. Fix that!");
-//                    continue;
-//                }
-//
-//                UploadTask uploadTask = new UploadTask(OCUpload);
-//                mUploadExecutor.submit(uploadTask);
-//            }
-//            StopSelfTask stopSelfTask = new StopSelfTask(intentStartId);
-//            mUploadExecutor.submit(stopSelfTask);
-//
-//        } else {
-//            stopSelf(intentStartId);
-//        }
-//
-//        Log_OC.d(TAG, "onHandleIntent end");
-//    }
-
-    // TODO: StopSelfTask not used in the new FileUploadService
-    // TODO: Remove when clean code
-    /**
-     * Stops this services if latest intent id is intentStartId.
-     */
-//    public class StopSelfTask implements Runnable {
-//        int intentStartId;
-//
-//        public StopSelfTask(int intentStartId) {
-//            this.intentStartId = intentStartId;
-//        }
-//
-//        @Override
-//        public void run() {
-//            stopSelf(intentStartId);
-//        }
-//    }
-
-    // TODO: UploaTask not used in the new FileUploadService
-    // TODO: Remove when clean code
-    /**
-     * Tries uploading OCUpload, creates notifications, and updates mUploadsStorageManager.
-     */
-//    public class UploadTask implements Runnable {
-//        OCUpload OCUpload;
-//
-//        public UploadTask(OCUpload OCUpload) {
-//            this.OCUpload = OCUpload;
-//        }
-//
-//        @Override
-//        public void run() {
-//            Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - before uploading.");
-//            switch (canUploadFileNow(OCUpload)) {
-//            case NOW:
-//                Log_OC.d(TAG, "Calling uploadFile for " + OCUpload.getRemotePath());
-//                RemoteOperationResult uploadResult = uploadFile(OCUpload);
-//                //TODO store renamed upload path?
-//                updateDatabaseUploadResult(uploadResult, mCurrentUpload);
-//                notifyUploadResult(uploadResult, mCurrentUpload);
-//                sendFinalBroadcast(uploadResult, mCurrentUpload);
-//                // TODO: Disable for testing of menu actions in uploads view
-////                if (!shouldRetryFailedUpload(uploadResult)) {
-////                    Log_OC.d(TAG, "Upload with result " + uploadResult.getCode() + ": " + uploadResult.getLogMessage()
-////                            + " will be abandoned.");
-////                    mPendingUploads.remove(buildRemoteName(OCUpload));
-////                }
-//                Log_OC.d(TAG, "mCurrentUpload = null");
-//                mCurrentUpload = null;
-//                break;
-//            case LATER:
-//                // Schedule retry for later upload. Delay can be due to:
-//                // KEY_WIFI_ONLY - done by ConnectivityActionReceiver
-//                // KEY_WHILE_CHARGING_ONLY - TODO add PowerConnectionReceiver
-//                // KEY_UPLOAD_TIMESTAMP - TODO use AlarmManager to wake up this service
-//                break;
-//            case FILE_GONE:
-//                mUploadsStorageManager.updateUploadStatus(
-//                        OCUpload.getLocalPath(),
-//                        UploadStatus.UPLOAD_FAILED_GIVE_UP,
-//                        com.owncloud.android.db.UploadResult.FILE_ERROR
-//                );
-//                if (mPendingUploads.remove(OCUpload.getRemotePath()) == null) {
-//                    Log_OC.w(TAG, "Could remove " + OCUpload.getRemotePath()
-//                            + " from mPendingUploads because it does not exist.");
-//                }
-//
-//                break;
-//            case ERROR:
-//                Log_OC.e(TAG, "canUploadFileNow() returned ERROR. Fix that!");
-//                break;
-//            }
-//            Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - after uploading.");
-//        }
-//
-//    }
-
-    /**
-     * Returns the reason as String why state of OCUpload is LATER. If
-     * upload state != LATER return null.
-     */
-    static public String getUploadLaterReason(Context context, OCUpload OCUpload) {
-        StringBuilder reason = new StringBuilder();
-        Date now = new Date();
-        if (now.getTime() < OCUpload.getUploadTimestamp()) {
-            reason.append(context.getString(R.string.uploads_view_later_reason_waiting_for) +
-                    DisplayUtils.unixTimeToHumanReadable(OCUpload.getUploadTimestamp()));
-        }
-        if (OCUpload.isUseWifiOnly() && !UploadUtils.isConnectedViaWiFi(context)) {
-            if (reason.length() > 0) {
-                reason.append(context.getString(R.string.uploads_view_later_reason_add_wifi_reason));
-            } else {
-                reason.append(context.getString(R.string.uploads_view_later_reason_waiting_for_wifi));
-            }
-        }
-        if (OCUpload.isWhileChargingOnly() && !UploadUtils.isCharging(context)) {
-            if (reason.length() > 0) {
-                reason.append(context.getString(R.string.uploads_view_later_reason_add_charging_reason));
-            } else {
-                reason.append(context.getString(R.string.uploads_view_later_reason_waiting_for_charging));
-            }
-        }
-        reason.append(".");
-        if (reason.length() > 1) {
-            return reason.toString();
-        }
-        if (OCUpload.getUploadStatus() == UploadStatus.UPLOAD_LATER) {
-            return context.getString(R.string.uploads_view_later_waiting_to_upload);
-        }
-        return null;
-    }
-    
-    enum CanUploadFileNowStatus {NOW, LATER, FILE_GONE, ERROR};
-    
-    /**
-     * Returns true when the file may be uploaded now. This methods checks all
-     * restraints of the passed {@link OCUpload}, these include
-     * isUseWifiOnly(), check if local file exists, check if file was already
-     * uploaded...
-     * 
-     * If return value is CanUploadFileNowStatus.NOW, uploadFile() may be
-     * called.
-     * 
-     * @return CanUploadFileNowStatus.NOW is upload may proceed, <br>
-     *         CanUploadFileNowStatus.LATER if upload should be performed at a
-     *         later time, <br>
-     *         CanUploadFileNowStatus.ERROR if a severe error happened, calling
-     *         entity should remove upload from queue.
-     * 
-     */
-    private CanUploadFileNowStatus canUploadFileNow(OCUpload OCUpload) {
-
-        if (OCUpload.getUploadStatus() == UploadStatus.UPLOAD_SUCCEEDED) {
-            Log_OC.w(TAG, "Already succeeded uploadObject was again scheduled for upload. Fix that!");
-            return CanUploadFileNowStatus.ERROR;
-        }
-
-        if (OCUpload.isUseWifiOnly()
-                && !UploadUtils.isConnectedViaWiFi(getApplicationContext())) {
-            Log_OC.d(TAG, "Do not start upload because it is wifi-only.");
-            return CanUploadFileNowStatus.LATER;
-        }
-        
-        if(OCUpload.isWhileChargingOnly() && !UploadUtils.isCharging(getApplicationContext())) {
-            Log_OC.d(TAG, "Do not start upload because it is while charging only.");
-            return CanUploadFileNowStatus.LATER;
-        }
-        Date now = new Date();
-        if (now.getTime() < OCUpload.getUploadTimestamp()) {
-            Log_OC.d(
-                    TAG,
-                    "Do not start upload because it is schedule for "
-                            + DisplayUtils.unixTimeToHumanReadable(OCUpload.getUploadTimestamp()));
-            return CanUploadFileNowStatus.LATER;
-        }
-        
-
-        if (!new File(OCUpload.getLocalPath()).exists()) {
-            Log_OC.d(TAG, "Do not start upload because local file does not exist.");
-            return CanUploadFileNowStatus.FILE_GONE;
-        }
-        return CanUploadFileNowStatus.NOW;        
-    }
-
-    /**
-     * Call if all pending uploads are to be retried.
-     */
-//    public static void retry(Context context) {
-//        retry(context, null);
-//    }
-
-    /**
-     * Call to retry upload identified by remotePath
-     */
-    private static void retry(Context context, Account account, OCUpload upload) {
-        Log_OC.d(TAG, "FileUploadService.retry()");
-        Intent i = new Intent(context, FileUploadService.class);
-        i.putExtra(FileUploadService.KEY_RETRY, true);
-        if(upload!= null) {
-            i.putExtra(FileUploadService.KEY_ACCOUNT, account);
-            i.putExtra(FileUploadService.KEY_RETRY_UPLOAD, upload);
-        }
-        context.startService(i);
-    }
-
-}

+ 467 - 120
src/com/owncloud/android/files/services/FileUploader.java

@@ -1,8 +1,12 @@
 /**
 /**
  *   ownCloud Android client application
  *   ownCloud Android client application
  *
  *
+ *   @author Bartek Przybylski
+ *   @authro masensio
+ *   @author LukeOwnCloud
+ *   @author David A. Velasco
  *   Copyright (C) 2012 Bartek Przybylski
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2015 ownCloud Inc.
+ *   Copyright (C) 2012-2016 ownCloud Inc.
  *
  *
  *   This program is free software: you can redistribute it and/or modify
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
  *   it under the terms of the GNU General Public License version 2,
@@ -26,6 +30,7 @@ import android.accounts.OnAccountsUpdateListener;
 import android.app.NotificationManager;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.app.Service;
+import android.content.Context;
 import android.content.Intent;
 import android.content.Intent;
 import android.os.Binder;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Handler;
@@ -33,7 +38,6 @@ import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Message;
-import android.os.Parcelable;
 import android.os.Process;
 import android.os.Process;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.NotificationCompat;
 import android.util.Pair;
 import android.util.Pair;
@@ -44,6 +48,10 @@ import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.UploadsStorageManager;
+import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
+import com.owncloud.android.db.OCUpload;
+import com.owncloud.android.db.UploadResult;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
@@ -63,7 +71,7 @@ import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.UploadFileOperation;
 import com.owncloud.android.operations.UploadFileOperation;
 import com.owncloud.android.operations.common.SyncOperation;
 import com.owncloud.android.operations.common.SyncOperation;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileActivity;
-import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.ui.activity.UploadListActivity;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.UriUtils;
 import com.owncloud.android.utils.UriUtils;
 
 
@@ -74,10 +82,25 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Map;
 import java.util.Vector;
 import java.util.Vector;
 
 
-
+/**
+ * Service for uploading files. Invoke using context.startService(...).
+ *
+ * Files to be uploaded are stored persistently using {@link UploadsStorageManager}.
+ *
+ * On next invocation of {@link FileUploader} uploaded files which
+ * previously failed will be uploaded again until either upload succeeded or a
+ * fatal error occured.
+ *
+ * Every file passed to this service is uploaded. No filtering is performed.
+ * However, Intent keys (e.g., KEY_WIFI_ONLY) are obeyed.
+ *
+ */
 public class FileUploader extends Service
 public class FileUploader extends Service
         implements OnDatatransferProgressListener, OnAccountsUpdateListener {
         implements OnDatatransferProgressListener, OnAccountsUpdateListener {
 
 
+    private static final String TAG = FileUploader.class.getSimpleName();
+
+    private static final String UPLOAD_START_MESSAGE = "UPLOAD_START";
     private static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
     private static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
     public static final String EXTRA_UPLOAD_RESULT = "RESULT";
     public static final String EXTRA_UPLOAD_RESULT = "RESULT";
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
@@ -91,13 +114,54 @@ public class FileUploader extends Service
     public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
     public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
     public static final String KEY_MIME_TYPE = "MIME_TYPE";
     public static final String KEY_MIME_TYPE = "MIME_TYPE";
 
 
+    /**
+     * Call this Service with only this Intent key if all pending uploads are to be retried.
+     */
+    private static final String KEY_RETRY = "KEY_RETRY";
+//    /**
+//     * Call this Service with KEY_RETRY and KEY_RETRY_REMOTE_PATH to retry
+//     * upload of file identified by KEY_RETRY_REMOTE_PATH.
+//     */
+//    private static final String KEY_RETRY_REMOTE_PATH = "KEY_RETRY_REMOTE_PATH";
+    /**
+     * Call this Service with KEY_RETRY and KEY_RETRY_UPLOAD to retry
+     * upload of file identified by KEY_RETRY_UPLOAD.
+     */
+    private static final String KEY_RETRY_UPLOAD = "KEY_RETRY_UPLOAD";
+    /**
+     * {@link Account} to which file is to be uploaded.
+     */
     public static final String KEY_ACCOUNT = "ACCOUNT";
     public static final String KEY_ACCOUNT = "ACCOUNT";
 
 
+    /**
+     * Set whether single file or multiple files are to be uploaded. SINGLE_FILES = 0, MULTIPLE_FILEs = 1.
+     */
     public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
     public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
+    /**
+     * Set to true if remote file is to be overwritten. Default action is to upload with different name.
+     */
     public static final String KEY_FORCE_OVERWRITE = "KEY_FORCE_OVERWRITE";
     public static final String KEY_FORCE_OVERWRITE = "KEY_FORCE_OVERWRITE";
-    public static final String KEY_INSTANT_UPLOAD = "INSTANT_UPLOAD";
+    /**
+     * Set to true if remote folder is to be created if it does not exist.
+     */
+    public static final String KEY_CREATE_REMOTE_FOLDER = "CREATE_REMOTE_FOLDER";
+    /**
+     * Set to true if upload is to performed only when connected via wifi.
+     */
+    public static final String KEY_WIFI_ONLY = "WIFI_ONLY";
+    /**
+     * Set to true if upload is to performed only when phone is being charged.
+     */
+    public static final String KEY_WHILE_CHARGING_ONLY = "KEY_WHILE_CHARGING_ONLY";
+//    /**
+//     * Set to future UNIX timestamp. Upload will not be performed before this timestamp.
+//     */
+//    public static final String KEY_UPLOAD_TIMESTAMP= "KEY_UPLOAD_TIMESTAMP";
+
     public static final String KEY_LOCAL_BEHAVIOUR = "BEHAVIOUR";
     public static final String KEY_LOCAL_BEHAVIOUR = "BEHAVIOUR";
 
 
+    //public static final String KEY_INSTANT_UPLOAD = "INSTANT_UPLOAD";
+
     public static final int LOCAL_BEHAVIOUR_COPY = 0;
     public static final int LOCAL_BEHAVIOUR_COPY = 0;
     public static final int LOCAL_BEHAVIOUR_MOVE = 1;
     public static final int LOCAL_BEHAVIOUR_MOVE = 1;
     public static final int LOCAL_BEHAVIOUR_FORGET = 2;
     public static final int LOCAL_BEHAVIOUR_FORGET = 2;
@@ -105,7 +169,62 @@ public class FileUploader extends Service
     public static final int UPLOAD_SINGLE_FILE = 0;
     public static final int UPLOAD_SINGLE_FILE = 0;
     public static final int UPLOAD_MULTIPLE_FILES = 1;
     public static final int UPLOAD_MULTIPLE_FILES = 1;
 
 
-    private static final String TAG = FileUploader.class.getSimpleName();
+    /**
+     * Describes local behavior for upload.
+     */
+//    public enum LocalBehaviour {
+//        /**
+//         * Creates a copy of file and stores it in tmp folder inside owncloud
+//         * folder on sd-card. After upload it is moved to local owncloud
+//         * storage. Original file stays untouched.
+//         */
+//        LOCAL_BEHAVIOUR_COPY(0),
+//        /**
+//         * Upload file from current storage. Afterwards original file is move to
+//         * local owncloud storage.
+//         */
+//        LOCAL_BEHAVIOUR_MOVE(1),
+//        /**
+//         * Just uploads file and leaves it where it is. Original file stays
+//         * untouched.
+//         */
+//        LOCAL_BEHAVIOUR_FORGET(2);
+//        private final int value;
+//
+//        LocalBehaviour(int value) {
+//            this.value = value;
+//        }
+//
+//        public int getValue() {
+//            return value;
+//        }
+//
+//        public static LocalBehaviour fromValue(int value){
+//            switch (value)
+//            {
+//                case 0:
+//                    return LOCAL_BEHAVIOUR_COPY;
+//                case 1:
+//                    return LOCAL_BEHAVIOUR_MOVE;
+//                case 2:
+//                    return LOCAL_BEHAVIOUR_FORGET;
+//            }
+//            return null;
+//        }
+//    }
+
+//    public enum UploadQuantity {
+//        UPLOAD_SINGLE_FILE(0), UPLOAD_MULTIPLE_FILES(1);
+//        private final int value;
+//
+//        UploadQuantity(int value) {
+//            this.value = value;
+//        }
+//
+//        public int getValue() {
+//            return value;
+//        }
+//    };
 
 
     private Looper mServiceLooper;
     private Looper mServiceLooper;
     private ServiceHandler mServiceHandler;
     private ServiceHandler mServiceHandler;
@@ -113,8 +232,14 @@ public class FileUploader extends Service
     private OwnCloudClient mUploadClient = null;
     private OwnCloudClient mUploadClient = null;
     private Account mCurrentAccount = null;
     private Account mCurrentAccount = null;
     private FileDataStorageManager mStorageManager;
     private FileDataStorageManager mStorageManager;
+    //since there can be only one instance of an Android service, there also just one db connection.
+    private UploadsStorageManager mUploadsStorageManager = null;
 
 
     private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<UploadFileOperation>();
     private IndexedForest<UploadFileOperation> mPendingUploads = new IndexedForest<UploadFileOperation>();
+
+    /**
+     * {@link UploadFileOperation} object of ongoing upload. Can be null. Note: There can only be one concurrent upload!
+     */
     private UploadFileOperation mCurrentUpload = null;
     private UploadFileOperation mCurrentUpload = null;
 
 
     private NotificationManager mNotificationManager;
     private NotificationManager mNotificationManager;
@@ -124,6 +249,9 @@ public class FileUploader extends Service
     private static final String MIME_TYPE_PDF = "application/pdf";
     private static final String MIME_TYPE_PDF = "application/pdf";
     private static final String FILE_EXTENSION_PDF = ".pdf";
     private static final String FILE_EXTENSION_PDF = ".pdf";
 
 
+    public static String getUploadStartMessage() {
+        return FileUploader.class.getName() + UPLOAD_START_MESSAGE;
+    }
 
 
     public static String getUploadFinishMessage() {
     public static String getUploadFinishMessage() {
         return FileUploader.class.getName() + UPLOAD_FINISH_MESSAGE;
         return FileUploader.class.getName() + UPLOAD_FINISH_MESSAGE;
@@ -137,7 +265,7 @@ public class FileUploader extends Service
      * @return 'True' if the ownCloud server with version supports chunked
      * @return 'True' if the ownCloud server with version supports chunked
      *         uploads.
      *         uploads.
      *
      *
-     * TODO - move to OCClient
+     * TODO - move to OwnCloudVersion
      */
      */
     private static boolean chunkedUploadIsSupported(OwnCloudVersion version) {
     private static boolean chunkedUploadIsSupported(OwnCloudVersion version) {
         return (version != null && version.compareTo(OwnCloudVersion.owncloud_v4_5) >= 0);
         return (version != null && version.compareTo(OwnCloudVersion.owncloud_v4_5) >= 0);
@@ -146,6 +274,7 @@ public class FileUploader extends Service
     /**
     /**
      * Service initialization
      * Service initialization
      */
      */
+    // TODO: Clean method: comments on extra code
     @Override
     @Override
     public void onCreate() {
     public void onCreate() {
         super.onCreate();
         super.onCreate();
@@ -158,6 +287,17 @@ public class FileUploader extends Service
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileUploaderBinder();
         mBinder = new FileUploaderBinder();
 
 
+        // From FileUploaderService
+        mUploadsStorageManager = new UploadsStorageManager(getContentResolver());
+
+        //when this service starts there is no upload in progress. if db says so, app probably crashed before.
+        //mUploadsStorageManager.setAllCurrentToUploadLater();  // TODO why?
+
+        // mUploadExecutor = Executors.newFixedThreadPool(1);
+
+//      Log_OC.d(TAG, "FileUploader.retry() called by onCreate()");
+//      FileUploader.retry(getApplicationContext());
+
         // add AccountsUpdatedListener
         // add AccountsUpdatedListener
         AccountManager am = AccountManager.get(getApplicationContext());
         AccountManager am = AccountManager.get(getApplicationContext());
         am.addOnAccountsUpdatedListener(this, null, false);
         am.addOnAccountsUpdatedListener(this, null, false);
@@ -168,7 +308,7 @@ public class FileUploader extends Service
      */
      */
     @Override
     @Override
     public void onDestroy() {
     public void onDestroy() {
-        Log_OC.v(TAG, "Destroying service" );
+        Log_OC.v(TAG, "Destroying service");
         mBinder = null;
         mBinder = null;
         mServiceHandler = null;
         mServiceHandler = null;
         mServiceLooper.quit();
         mServiceLooper.quit();
@@ -194,130 +334,204 @@ public class FileUploader extends Service
     public int onStartCommand(Intent intent, int flags, int startId) {
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log_OC.d(TAG, "Starting command with id " + 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))) {
+        boolean retry = intent.getBooleanExtra(KEY_RETRY, false);
+        AbstractList<String> requestedUploads = new Vector<String>();
+
+        if (!intent.hasExtra(KEY_ACCOUNT)) {
             Log_OC.e(TAG, "Not enough information provided in intent");
             Log_OC.e(TAG, "Not enough information provided in intent");
             return Service.START_NOT_STICKY;
             return Service.START_NOT_STICKY;
         }
         }
-        int uploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
-        if (uploadType == -1) {
-            Log_OC.e(TAG, "Incorrect upload type provided");
-            return Service.START_NOT_STICKY;
-        }
+
         Account account = intent.getParcelableExtra(KEY_ACCOUNT);
         Account account = intent.getParcelableExtra(KEY_ACCOUNT);
         if (!AccountUtils.exists(account, getApplicationContext())) {
         if (!AccountUtils.exists(account, getApplicationContext())) {
             return Service.START_NOT_STICKY;
             return Service.START_NOT_STICKY;
         }
         }
+        OwnCloudVersion ocv = AccountUtils.getServerVersion(account);
+        boolean chunked = FileUploader.chunkedUploadIsSupported(ocv);
+
+        if (!retry) {
+            if (!intent.hasExtra(KEY_UPLOAD_TYPE) || !(intent.hasExtra(KEY_LOCAL_FILE) ||
+                    intent.hasExtra(KEY_FILE))) {
+                Log_OC.e(TAG, "Not enough information provided in intent");
+                return Service.START_NOT_STICKY;
+            }
+            int uploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
+            if (uploadType == -1) {
+                Log_OC.e(TAG, "Incorrect upload type provided");
+                return Service.START_NOT_STICKY;
+            }
 
 
-        String[] localPaths = null, remotePaths = null, mimeTypes = null;
-        OCFile[] files = null;
-        if (uploadType == UPLOAD_SINGLE_FILE) {
+            String[] localPaths = null, remotePaths = null, mimeTypes = null;
+            OCFile[] files = null;
+            if (uploadType == UPLOAD_SINGLE_FILE) {
 
 
-            if (intent.hasExtra(KEY_FILE)) {
-                files = new OCFile[] { intent.getParcelableExtra(KEY_FILE) };
+                if (intent.hasExtra(KEY_FILE)) {
+                    files = new OCFile[]{intent.getParcelableExtra(KEY_FILE)};
 
 
-            } else {
-                localPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
-                remotePaths = new String[] { intent.getStringExtra(KEY_REMOTE_FILE) };
-                mimeTypes = new String[] { intent.getStringExtra(KEY_MIME_TYPE) };
-            }
+                } else {
+                    localPaths = new String[]{intent.getStringExtra(KEY_LOCAL_FILE)};
+                    remotePaths = new String[]{intent.getStringExtra(KEY_REMOTE_FILE)};
+                    mimeTypes = new String[]{intent.getStringExtra(KEY_MIME_TYPE)};
+                }
 
 
-        } else { // mUploadType == UPLOAD_MULTIPLE_FILES
+            } else { // mUploadType == UPLOAD_MULTIPLE_FILES
 
 
-            if (intent.hasExtra(KEY_FILE)) {
-                files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE); // TODO
-                                                                             // will
-                                                                             // this
-                                                                             // casting
-                                                                             // work
-                                                                             // fine?
+                if (intent.hasExtra(KEY_FILE)) {
+                    files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE);
+                    // TODO : test multiple upload, working find
 
 
-            } else {
-                localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
-                remotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
-                mimeTypes = intent.getStringArrayExtra(KEY_MIME_TYPE);
+                } else {
+                    localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
+                    remotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
+                    mimeTypes = intent.getStringArrayExtra(KEY_MIME_TYPE);
+                }
             }
             }
-        }
 
 
-        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);
-        int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_FORGET);
+            boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
+            //boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
+            int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_FORGET);
 
 
-        if (intent.hasExtra(KEY_FILE) && files == null) {
-            Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
-            return Service.START_NOT_STICKY;
+            boolean isCreateRemoteFolder = intent.getBooleanExtra(KEY_CREATE_REMOTE_FOLDER, false);
+            boolean isUseWifiOnly = intent.getBooleanExtra(KEY_WIFI_ONLY, true);
+            boolean isWhileChargingOnly = intent.getBooleanExtra(KEY_WHILE_CHARGING_ONLY, false);
+            //long uploadTimestamp = intent.getLongExtra(KEY_UPLOAD_TIMESTAMP, -1);
 
 
-        } else if (!intent.hasExtra(KEY_FILE)) {
-            if (localPaths == null) {
-                Log_OC.e(TAG, "Incorrect array for local paths provided in upload intent");
-                return Service.START_NOT_STICKY;
-            }
-            if (remotePaths == null) {
-                Log_OC.e(TAG, "Incorrect array for remote paths provided in upload intent");
-                return Service.START_NOT_STICKY;
-            }
-            if (localPaths.length != remotePaths.length) {
-                Log_OC.e(TAG, "Different number of remote paths and local paths!");
+
+            if (intent.hasExtra(KEY_FILE) && files == null) {
+                Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
                 return Service.START_NOT_STICKY;
                 return Service.START_NOT_STICKY;
-            }
 
 
-            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));
-                if (files[i] == null) {
-                    // TODO @andomaex add failure Notification
+            } else if (!intent.hasExtra(KEY_FILE)) {
+                if (localPaths == null) {
+                    Log_OC.e(TAG, "Incorrect array for local paths provided in upload intent");
+                    return Service.START_NOT_STICKY;
+                }
+                if (remotePaths == null) {
+                    Log_OC.e(TAG, "Incorrect array for remote paths provided in upload intent");
+                    return Service.START_NOT_STICKY;
+                }
+                if (localPaths.length != remotePaths.length) {
+                    Log_OC.e(TAG, "Different number of remote paths and local paths!");
                     return Service.START_NOT_STICKY;
                     return Service.START_NOT_STICKY;
                 }
                 }
-            }
-        }
 
 
-        OwnCloudVersion ocv = AccountUtils.getServerVersion(account);
+                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));
+                    if (files[i] == null) {
+                        Log_OC.e(TAG, "obtainNewOCFileToUpload() returned null for remotePaths[i]:" + remotePaths[i]
+                                + " and localPaths[i]:" + localPaths[i]);
+                        return Service.START_NOT_STICKY;
+                    }
 
 
-        boolean chunked = FileUploader.chunkedUploadIsSupported(ocv);
-        AbstractList<String> requestedUploads = new Vector<String>();
-        String uploadKey = null;
-        UploadFileOperation newUpload = null;
-        try {
-            for (int i = 0; i < files.length; i++) {
-                newUpload = new UploadFileOperation(
-                        account,
-                        files[i],
-                        chunked,
-                        forceOverwrite,
-                        localAction, // Change for compilation
-                        getApplicationContext()
-                );
-                if (isInstant) {
-                    newUpload.setRemoteFolderToBeCreated();
+                    // don't use mStorageManager here; it's bound to an account, that varies per request
+                    storageManager.saveNewFile(files[i]);
+                    files[i] = storageManager.getFileByLocalPath(files[i].getStoragePath());
                 }
                 }
-                newUpload.addDatatransferProgressListener(this);
-                newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
-                Pair<String, String> putResult = mPendingUploads.putIfAbsent(
-                        account, files[i].getRemotePath(), newUpload, null
-                );
-                if (putResult != null) {
-                    uploadKey = putResult.first;
-                    requestedUploads.add(uploadKey);
-                }   // else, file already in the queue of uploads; don't repeat the request
             }
             }
+            // at this point variable "OCFile[] files" is loaded correctly.
 
 
-        } catch (IllegalArgumentException e) {
-            Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
-            return START_NOT_STICKY;
+            String uploadKey = null;
+            UploadFileOperation newUpload = null;
+            try {
+                for (int i = 0; i < files.length; i++) {
+                    newUpload = new UploadFileOperation(
+                            account,
+                            files[i],
+                            chunked,
+                            forceOverwrite,
+                            localAction,
+                            getApplicationContext()
+                    );
+                    if (isCreateRemoteFolder) {
+                        newUpload.setRemoteFolderToBeCreated();
+                    }
+                    newUpload.addDatatransferProgressListener(this);
+                    newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
+
+                    // Save upload in database
+                    OCUpload ocUpload = new OCUpload(files[i]);
+                    ocUpload.setAccountName(account.name);
+                    ocUpload.setForceOverwrite(forceOverwrite);
+                    ocUpload.setCreateRemoteFolder(isCreateRemoteFolder);
+                    ocUpload.setLocalAction(localAction);
+                    ocUpload.setUseWifiOnly(isUseWifiOnly);
+                    ocUpload.setWhileChargingOnly(isWhileChargingOnly);
+//                    ocUpload.setUploadTimestamp(uploadTimestamp);
+                    ocUpload.setUploadStatus(UploadStatus.UPLOAD_LATER);
+
+                    // storagePath inside upload is the temporary path. file
+                    // contains the correct path used as db reference.
+                    long id = mUploadsStorageManager.storeUpload(ocUpload);
+                    newUpload.setOCUploadId(id);
+
+                    Pair<String, String> putResult = mPendingUploads.putIfAbsent(
+                            account, files[i].getRemotePath(), newUpload, /*String.valueOf(id)*/ null
+                    );
+                    if (putResult != null) {
+                        uploadKey = putResult.first;
+                        requestedUploads.add(uploadKey);
+                    } else {
+                        mUploadsStorageManager.removeUpload(id);
+                    }
+                    // else, file already in the queue of uploads; don't repeat the request
+                }
+
+            } catch (IllegalArgumentException e) {
+                Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
+                return START_NOT_STICKY;
 
 
-        } catch (IllegalStateException e) {
-            Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
-            return START_NOT_STICKY;
+            } catch (IllegalStateException e) {
+                Log_OC.e(TAG, "Bad information provided in intent: " + e.getMessage());
+                return START_NOT_STICKY;
+
+            } catch (Exception e) {
+                Log_OC.e(TAG, "Unexpected exception while processing upload intent", e);
+                return START_NOT_STICKY;
+
+            }
+            // *** TODO REWRITE: block inserted to request retries in a raw; too many code copied, no control exception ***/
+        } else {
+            if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_RETRY_UPLOAD)) {
+                Log_OC.e(TAG, "Not enough information provided in intent: no KEY_RETRY_UPLOAD_KEY");
+                return START_NOT_STICKY;
+            }
+            OCUpload upload = intent.getParcelableExtra(KEY_RETRY_UPLOAD);
+
+            UploadFileOperation newUpload = new UploadFileOperation(
+                    account,
+                    upload.getOCFile(),
+                    chunked,
+                    upload.isForceOverwrite(),
+                    upload.getLocalAction(),
+                    getApplicationContext()
+            );
+            if (upload.isCreateRemoteFolder()) {
+                newUpload.setRemoteFolderToBeCreated();
+            }
+            newUpload.addDatatransferProgressListener(this);
+            newUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
+            newUpload.setOCUploadId(upload.getUploadId());
 
 
-        } catch (Exception e) {
-            Log_OC.e(TAG, "Unexpected exception while processing upload intent", e);
-            return START_NOT_STICKY;
+            Pair<String, String> putResult = mPendingUploads.putIfAbsent(
+                    account, upload.getOCFile().getRemotePath(), newUpload, String.valueOf(upload.getUploadId())
+            );
+            if (putResult != null) {
+                String uploadKey = putResult.first;
+                requestedUploads.add(uploadKey);
 
 
+                // Update upload in database
+                upload.setUploadStatus(UploadStatus.UPLOAD_LATER);
+                mUploadsStorageManager.updateUpload(upload);
+            }
         }
         }
+        // *** TODO REWRITE END ***/
 
 
         if (requestedUploads.size() > 0) {
         if (requestedUploads.size() > 0) {
             Message msg = mServiceHandler.obtainMessage();
             Message msg = mServiceHandler.obtainMessage();
@@ -386,10 +600,31 @@ public class FileUploader extends Service
             if (upload != null) {
             if (upload != null) {
                 upload.cancel();
                 upload.cancel();
             } else {
             } else {
+                // updating current references (i.e., uploadStatus of current
+                // upload) is handled by updateDataseUploadResult() which is called
+                // after upload finishes. Following cancel call makes sure that is
+                // does finish right now.
                 if (mCurrentUpload != null && mCurrentAccount != null &&
                 if (mCurrentUpload != null && mCurrentAccount != null &&
+                        mCurrentUpload.isUploadInProgress() &&  // TODO added with reliale_uploads, to check
                         mCurrentUpload.getRemotePath().startsWith(file.getRemotePath()) &&
                         mCurrentUpload.getRemotePath().startsWith(file.getRemotePath()) &&
-                        account.name.equals(mCurrentAccount.name)) {
+                        account.name.equals(mCurrentAccount.name) ) {
+                    Log_OC.d(TAG, "Calling cancel for " + file.getRemotePath() + " during upload operation.");
                     mCurrentUpload.cancel();
                     mCurrentUpload.cancel();
+//            } else if(mCancellationPossible.get()){
+//                Log_OC.d(TAG, "Calling cancel for " + file.getRemotePath() + " during preparing for upload.");
+//                mCancellationRequested.set(true);
+                } else {
+                    Log_OC.d(TAG, "Calling cancel for " + file.getRemotePath() + " while upload is pending.");
+                    // upload not in progress, but pending.
+                    // in this case we have to update the db here.
+                    //OCUpload upload = mPendingUploads.remove(buildRemoteName(account, file));
+                    OCUpload ocUpload = mUploadsStorageManager.getUploadByLocalPath(upload.getStoragePath())[0];
+                    ocUpload.setUploadStatus(UploadStatus.UPLOAD_CANCELLED);
+                    ocUpload.setLastResult(UploadResult.CANCELLED);
+                    // storagePath inside upload is the temporary path. file
+                    // contains the correct path used as db reference.
+                    ocUpload.getOCFile().setStoragePath(file.getStoragePath());
+                    mUploadsStorageManager.updateUploadStatus(ocUpload);
                 }
                 }
             }
             }
         }
         }
@@ -412,11 +647,42 @@ public class FileUploader extends Service
             cancelUploadsForAccount(account);
             cancelUploadsForAccount(account);
         }
         }
 
 
+        // TODO: Review: Method from FileUploadService with some changes because the merge with FileUploader
+        public void remove(Account account, OCFile file) {
+            Pair<UploadFileOperation, String> removeResult = mPendingUploads.remove(account, file.getRemotePath());
+            UploadFileOperation upload = removeResult.first;
+            //OCUpload upload = mPendingUploads.remove(buildRemoteName(account, file));
+            if(upload == null) {
+                Log_OC.e(TAG, "Could not delete upload " + file + " from mPendingUploads.");
+            }
+            int d = mUploadsStorageManager.removeUpload(upload.getStoragePath());
+            if(d == 0) {
+                Log_OC.e(TAG, "Could not delete upload "+ file.getStoragePath() +" from database.");
+            }
+        }
+
+        public void remove(OCUpload upload) {
+            int d = mUploadsStorageManager.removeUpload(upload.getUploadId());
+            if(d == 0) {
+                Log_OC.e(TAG, "Could not delete upload "+ upload.getRemotePath() +" from database.");
+            }
+        }
+
+        // TODO: Review: Method from FileUploader with some changes because the merge with FileUploader
+        // TODO Complete operation to retry the upload
+        /**
+         * Puts upload in upload list and tell FileUploader to upload items in list.
+         */
+        public void retry(Account account, OCUpload upload) {
+//            String uploadKey = buildRemoteName(account, upload.getOCFile());
+//            mPendingUploads.put(uploadKey, upload);
+            FileUploader.retry(getApplicationContext(), account, upload);
+        }
+
         public void clearListeners() {
         public void clearListeners() {
             mBoundListeners.clear();
             mBoundListeners.clear();
         }
         }
 
 
-
         /**
         /**
          * Returns True when the file described by 'file' is being uploaded to
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
          * the ownCloud account 'account' or waiting for it
@@ -424,11 +690,16 @@ public class FileUploader extends Service
          * If 'file' is a directory, returns 'true' if some of its descendant files
          * If 'file' is a directory, returns 'true' if some of its descendant files
          * is uploading or waiting to upload.
          * 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
+         * Warning: If remote file exists and !forceOverwrite the original file
+         * is being returned here. That is, it seems as if the original file is
+         * being updated when actually a new file is being uploaded.
+         *
+         * @param account Owncloud account where the remote file will be stored.
+         * @param file A file that could be in the queue of pending uploads
          */
          */
         public boolean isUploading(Account account, OCFile file) {
         public boolean isUploading(Account account, OCFile file) {
-            if (account == null || file == null) return false;
+            if (account == null || file == null)
+                return false;
             return (mPendingUploads.contains(account, file.getRemotePath()));
             return (mPendingUploads.contains(account, file.getRemotePath()));
         }
         }
 
 
@@ -466,6 +737,7 @@ public class FileUploader extends Service
         }
         }
 
 
 
 
+        // TODO: Review: Method from FileUploader with some changes because the merge with FileUploader
         @Override
         @Override
         public void onTransferProgress(long progressRate, long totalTransferredSoFar,
         public void onTransferProgress(long progressRate, long totalTransferredSoFar,
                                        long totalToTransfer, String fileName) {
                                        long totalToTransfer, String fileName) {
@@ -490,6 +762,13 @@ public class FileUploader extends Service
         private String buildRemoteName(Account account, OCFile file) {
         private String buildRemoteName(Account account, OCFile file) {
             return account.name + file.getRemotePath();
             return account.name + file.getRemotePath();
         }
         }
+        /*private String buildRemoteName(Account account, OCFile file, long uploadId) {
+            String suffix = String.valueOf(uploadId);
+            if (uploadId != -1) {
+                suffix = "";
+            }
+            return account.name + file.getRemotePath() + suffix;
+        }*/
 
 
     }
     }
 
 
@@ -541,6 +820,8 @@ public class FileUploader extends Service
             if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
             if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
                 Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().name + " exists");
                 Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().name + " exists");
 
 
+                mUploadsStorageManager.updateDatabaseUploadStart(mCurrentUpload);
+
                 notifyUploadStart(mCurrentUpload);
                 notifyUploadStart(mCurrentUpload);
 
 
                 RemoteOperationResult uploadResult = null, grantResult;
                 RemoteOperationResult uploadResult = null, grantResult;
@@ -569,8 +850,8 @@ public class FileUploader extends Service
 
 
                     /// perform the upload
                     /// perform the upload
                     if (grantResult.isSuccess()) {
                     if (grantResult.isSuccess()) {
-                        OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
-                        mCurrentUpload.getFile().setParentId(parent.getFileId());
+                        /*OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
+                        mCurrentUpload.getFile().setParentId(parent.getFileId());*/
                         uploadResult = mCurrentUpload.execute(mUploadClient);
                         uploadResult = mCurrentUpload.execute(mUploadClient);
                         if (uploadResult.isSuccess()) {
                         if (uploadResult.isSuccess()) {
                             saveUploadedFile();
                             saveUploadedFile();
@@ -594,6 +875,9 @@ public class FileUploader extends Service
                                 mCurrentAccount,
                                 mCurrentAccount,
                                 mCurrentUpload.getOldFile().getRemotePath()
                                 mCurrentUpload.getOldFile().getRemotePath()
                         );
                         );
+                        /** TODO NOW: double check */
+                        mUploadsStorageManager.updateFileIdUpload(mCurrentUpload.getOCUploadId(),
+                                mCurrentUpload.getFile().getFileId());
                     } else {
                     } else {
                         removeResult = mPendingUploads.removePayload(
                         removeResult = mPendingUploads.removePayload(
                                 mCurrentAccount,
                                 mCurrentAccount,
@@ -601,6 +885,8 @@ public class FileUploader extends Service
                         );
                         );
                     }
                     }
 
 
+                    mUploadsStorageManager.updateDatabaseUploadResult(uploadResult, mCurrentUpload);
+
                     /// notify result
                     /// notify result
                     notifyUploadResult(mCurrentUpload, uploadResult);
                     notifyUploadResult(mCurrentUpload, uploadResult);
 
 
@@ -716,7 +1002,7 @@ public class FileUploader extends Service
         file.setNeedsUpdateThumbnail(true);
         file.setNeedsUpdateThumbnail(true);
         mStorageManager.saveFile(file);
         mStorageManager.saveFile(file);
         mStorageManager.saveConflict(file, null);
         mStorageManager.saveConflict(file, null);
-        
+
         mStorageManager.triggerMediaScan(file.getStoragePath());
         mStorageManager.triggerMediaScan(file.getStoragePath());
 
 
     }
     }
@@ -789,16 +1075,28 @@ public class FileUploader extends Service
                 .setContentText(
                 .setContentText(
                         String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName()));
                         String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName()));
 
 
+        /// includes a pending intent in the notification showing the details
+        Intent showUploadListIntent = new Intent(this, UploadListActivity.class);
+        showUploadListIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile());
+        showUploadListIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
+        showUploadListIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(this, (int) System.currentTimeMillis(),
+                showUploadListIntent, 0));
+
+        // TODO: decide where do we go to navigate when the user clicks the notification
         /// includes a pending intent in the notification showing the details view of the file
         /// includes a pending intent in the notification showing the details view of the file
-        Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class);
-        showDetailsIntent.putExtra(FileActivity.EXTRA_FILE,  (Parcelable) upload.getFile());
-        showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
-        showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-                this, (int) System.currentTimeMillis(), showDetailsIntent, 0
-        ));
+//        Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class);
+//        showDetailsIntent.putExtra(FileActivity.EXTRA_FILE,  (Parcelable) upload.getFile());
+//        showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
+//        showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+//        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
+//                this, (int) System.currentTimeMillis(), showDetailsIntent, 0
+//        ));
 
 
         mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
         mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
+
+        // TODO really needed?
+        sendBroadcastUploadStarted(mCurrentUpload);
     }
     }
 
 
     /**
     /**
@@ -810,8 +1108,7 @@ public class FileUploader extends Service
         int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         if (percent != mLastPercent) {
         if (percent != mLastPercent) {
             mNotificationBuilder.setProgress(100, percent, false);
             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);
             String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName);
             mNotificationBuilder.setContentText(text);
             mNotificationBuilder.setContentText(text);
             mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
             mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
@@ -910,6 +1207,16 @@ public class FileUploader extends Service
 //                }
 //                }
             }
             }
 
 
+            if(!uploadResult.isSuccess()){
+                //in case of failure, do not show details file view (because there is no file!)
+                Intent showUploadListIntent = new Intent(this, UploadListActivity.class);
+                showUploadListIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile());
+                showUploadListIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
+                showUploadListIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                mNotificationBuilder.setContentIntent(PendingIntent.getActivity(this, (int) System.currentTimeMillis(),
+                        showUploadListIntent, 0));
+            }
+
             mNotificationBuilder.setContentText(content);
             mNotificationBuilder.setContentText(content);
             mNotificationManager.notify(tickerId, mNotificationBuilder.build());
             mNotificationManager.notify(tickerId, mNotificationBuilder.build());
 
 
@@ -918,17 +1225,34 @@ public class FileUploader extends Service
 //                DbHandler db = new DbHandler(this.getBaseContext());
 //                DbHandler db = new DbHandler(this.getBaseContext());
 //                db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
 //                db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
 //                db.close();
 //                db.close();
-
+                mPendingUploads.remove(upload.getAccount(), upload.getFile().getRemotePath());
+                //updateDatabaseUploadResult(uploadResult, mCurrentUpload);
                 // remove success notification, with a delay of 2 seconds
                 // remove success notification, with a delay of 2 seconds
                 NotificationDelayer.cancelWithDelay(
                 NotificationDelayer.cancelWithDelay(
                         mNotificationManager,
                         mNotificationManager,
                         R.string.uploader_upload_succeeded_ticker,
                         R.string.uploader_upload_succeeded_ticker,
                         2000);
                         2000);
-
             }
             }
         }
         }
     }
     }
 
 
+    /**
+     * Sends a broadcast in order to the interested activities can update their
+     * view
+     *
+     * @param upload                    Finished upload operation
+     */
+    private void sendBroadcastUploadStarted(
+            UploadFileOperation upload) {
+
+        Intent start = new Intent(getUploadStartMessage());
+        start.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
+        start.putExtra(EXTRA_OLD_FILE_PATH, upload.getOriginalStoragePath());
+        start.putExtra(ACCOUNT_NAME, upload.getAccount().name);
+
+        sendStickyBroadcast(start);
+    }
+
     /**
     /**
      * Sends a broadcast in order to the interested activities can update their
      * Sends a broadcast in order to the interested activities can update their
      * view
      * view
@@ -986,4 +1310,27 @@ public class FileUploader extends Service
         // Cancel pending uploads
         // Cancel pending uploads
         mPendingUploads.remove(account);
         mPendingUploads.remove(account);
     }
     }
+
+    /**
+     * Call if all pending uploads are to be retried.
+     */
+//    public static void retry(Context context) {
+//        retry(context, null);
+//    }
+
+    /**
+     * Call to retry upload identified by remotePath
+     */
+    private static void retry(Context context, Account account, OCUpload upload) {
+        Log_OC.d(TAG, "FileUploader.retry()");
+        Intent i = new Intent(context, FileUploader.class);
+        i.putExtra(FileUploader.KEY_RETRY, true);
+        if(upload!= null) {
+            i.putExtra(FileUploader.KEY_ACCOUNT, account);
+            i.putExtra(FileUploader.KEY_RETRY_UPLOAD, upload);
+        }
+        context.startService(i);
+    }
+
+
 }
 }

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

@@ -29,7 +29,7 @@ import android.os.Parcelable;
 
 
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
@@ -285,16 +285,16 @@ public class SynchronizeFileOperation extends SyncOperation {
      * @param file     OCFile object representing the file to upload
      * @param file     OCFile object representing the file to upload
      */
      */
     private void requestForUpload(OCFile file) {
     private void requestForUpload(OCFile file) {
-        Intent i = new Intent(mContext, FileUploadService.class);
-        i.putExtra(FileUploadService.KEY_ACCOUNT, mAccount);
-        i.putExtra(FileUploadService.KEY_FILE, file);
+        Intent i = new Intent(mContext, FileUploader.class);
+        i.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
+        i.putExtra(FileUploader.KEY_FILE, file);
         /*i.putExtra(FileUploader.KEY_REMOTE_FILE, mRemotePath);
         /*i.putExtra(FileUploader.KEY_REMOTE_FILE, mRemotePath);
         // doing this we would lose the value of keepInSync in the road, and maybe it's not updated
         // doing this we would lose the value of keepInSync in the road, and maybe it's not updated
         in the database when the FileUploader service gets it!
         in the database when the FileUploader service gets it!
         i.putExtra(FileUploader.KEY_LOCAL_FILE, localFile.getStoragePath());*/
         i.putExtra(FileUploader.KEY_LOCAL_FILE, localFile.getStoragePath());*/
-        i.putExtra(FileUploadService.KEY_UPLOAD_TYPE,
-                FileUploadService.UPLOAD_SINGLE_FILE);
-        i.putExtra(FileUploadService.KEY_FORCE_OVERWRITE, true);
+        i.putExtra(FileUploader.KEY_UPLOAD_TYPE,
+                FileUploader.UPLOAD_SINGLE_FILE);
+        i.putExtra(FileUploader.KEY_FORCE_OVERWRITE, true);
         mContext.startService(i);
         mContext.startService(i);
         mTransferWasRequested = true;
         mTransferWasRequested = true;
     }
     }

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

@@ -27,7 +27,7 @@ import android.net.Uri;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
 import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
@@ -79,7 +79,7 @@ public class UploadFileOperation extends RemoteOperation {
     private boolean mChunked = false;
     private boolean mChunked = false;
     private boolean mRemoteFolderToBeCreated = false;
     private boolean mRemoteFolderToBeCreated = false;
     private boolean mForceOverwrite = false;
     private boolean mForceOverwrite = false;
-    private int mLocalBehaviour = FileUploadService.LOCAL_BEHAVIOUR_COPY;
+    private int mLocalBehaviour = FileUploader.LOCAL_BEHAVIOUR_COPY;
     private boolean mWasRenamed = false;
     private boolean mWasRenamed = false;
     private String mOriginalFileName = null;
     private String mOriginalFileName = null;
     private long mOCUploadId = -1;
     private long mOCUploadId = -1;
@@ -245,7 +245,7 @@ public class UploadFileOperation extends RemoteOperation {
             // check location of local file; if not the expected, copy to a
             // check location of local file; if not the expected, copy to a
             // temporal file before upload (if COPY is the expected behaviour)
             // temporal file before upload (if COPY is the expected behaviour)
             if (!mOriginalStoragePath.equals(expectedPath) &&
             if (!mOriginalStoragePath.equals(expectedPath) &&
-                    mLocalBehaviour == FileUploadService.LOCAL_BEHAVIOUR_COPY) {
+                    mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY) {
 
 
 
 
                 if (FileStorageUtils.getUsableSpace(mAccount.name) < originalFile.length()) {
                 if (FileStorageUtils.getUsableSpace(mAccount.name) < originalFile.length()) {
@@ -368,7 +368,7 @@ public class UploadFileOperation extends RemoteOperation {
             /// move local temporal file or original file to its corresponding
             /// move local temporal file or original file to its corresponding
             // location in the ownCloud local folder
             // location in the ownCloud local folder
             if (result.isSuccess()) {
             if (result.isSuccess()) {
-                if (mLocalBehaviour == FileUploadService.LOCAL_BEHAVIOUR_FORGET) {
+                if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
                     mFile.setStoragePath("");
                     mFile.setStoragePath("");
                 } else {
                 } else {
                     mFile.setStoragePath(expectedPath);
                     mFile.setStoragePath(expectedPath);

+ 1 - 1
src/com/owncloud/android/ui/activity/ComponentsGetter.java

@@ -23,7 +23,7 @@ package com.owncloud.android.ui.activity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.files.FileOperationsHelper;
 import com.owncloud.android.files.FileOperationsHelper;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 
 
 public interface ComponentsGetter {
 public interface ComponentsGetter {

+ 7 - 7
src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java

@@ -27,7 +27,7 @@ import android.os.Bundle;
 
 
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog.Decision;
 import com.owncloud.android.ui.dialog.ConflictsResolveDialog.Decision;
@@ -49,7 +49,7 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict
 
 
     @Override
     @Override
     public void conflictDecisionMade(Decision decision) {
     public void conflictDecisionMade(Decision decision) {
-        Intent i = new Intent(getApplicationContext(), FileUploadService.class);
+        Intent i = new Intent(getApplicationContext(), FileUploader.class);
         
         
         switch (decision) {
         switch (decision) {
             case CANCEL:
             case CANCEL:
@@ -57,10 +57,10 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict
                 return;
                 return;
             case OVERWRITE:
             case OVERWRITE:
                 // use local version -> overwrite on server
                 // use local version -> overwrite on server
-                i.putExtra(FileUploadService.KEY_FORCE_OVERWRITE, true);
+                i.putExtra(FileUploader.KEY_FORCE_OVERWRITE, true);
                 break;
                 break;
             case KEEP_BOTH:
             case KEEP_BOTH:
-                i.putExtra(FileUploadService.KEY_LOCAL_BEHAVIOUR, FileUploadService.LOCAL_BEHAVIOUR_MOVE);
+                i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
                 break;
                 break;
             case SERVER:
             case SERVER:
                 // use server version -> delete local, request download
                 // use server version -> delete local, request download
@@ -74,9 +74,9 @@ public class ConflictsResolveActivity extends FileActivity implements OnConflict
                 Log_OC.wtf(TAG, "Unhandled conflict decision " + decision);
                 Log_OC.wtf(TAG, "Unhandled conflict decision " + decision);
                 return;
                 return;
         }
         }
-        i.putExtra(FileUploadService.KEY_ACCOUNT, getAccount());
-        i.putExtra(FileUploadService.KEY_FILE, getFile());
-        i.putExtra(FileUploadService.KEY_UPLOAD_TYPE, FileUploadService.UPLOAD_SINGLE_FILE);
+        i.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
+        i.putExtra(FileUploader.KEY_FILE, getFile());
+        i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
         
         
         startService(i);
         startService(i);
         finish();
         finish();

+ 3 - 3
src/com/owncloud/android/ui/activity/FileActivity.java

@@ -60,9 +60,9 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.FileOperationsHelper;
 import com.owncloud.android.files.FileOperationsHelper;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
-import com.owncloud.android.files.services.FileUploadService;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
@@ -219,7 +219,7 @@ public class FileActivity extends AppCompatActivity
         }
         }
         mUploadServiceConnection = newTransferenceServiceConnection();
         mUploadServiceConnection = newTransferenceServiceConnection();
         if (mUploadServiceConnection != null) {
         if (mUploadServiceConnection != null) {
-            bindService(new Intent(this, FileUploadService.class), mUploadServiceConnection,
+            bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
                     Context.BIND_AUTO_CREATE);
                     Context.BIND_AUTO_CREATE);
         }
         }
 
 

+ 27 - 27
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -63,8 +63,8 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.network.CertificateCombinedException;
 import com.owncloud.android.lib.common.network.CertificateCombinedException;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -681,14 +681,14 @@ public class FileDisplayActivity extends HookActivity implements
                 remotePaths[j] = remotePathBase + (new File(filePaths[j])).getName();
                 remotePaths[j] = remotePathBase + (new File(filePaths[j])).getName();
             }
             }
 
 
-            Intent i = new Intent(this, FileUploadService.class);
-            i.putExtra(FileUploadService.KEY_ACCOUNT, getAccount());
-            i.putExtra(FileUploadService.KEY_LOCAL_FILE, filePaths);
-            i.putExtra(FileUploadService.KEY_REMOTE_FILE, remotePaths);
-            i.putExtra(FileUploadService.KEY_UPLOAD_TYPE,
-                    FileUploadService.UPLOAD_MULTIPLE_FILES);
+            Intent i = new Intent(this, FileUploader.class);
+            i.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
+            i.putExtra(FileUploader.KEY_LOCAL_FILE, filePaths);
+            i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePaths);
+            i.putExtra(FileUploader.KEY_UPLOAD_TYPE,
+                    FileUploader.UPLOAD_MULTIPLE_FILES);
             if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
             if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
-                i.putExtra(FileUploadService.KEY_LOCAL_BEHAVIOUR, FileUploadService.LOCAL_BEHAVIOUR_MOVE);
+                i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
             startService(i);
             startService(i);
 
 
         } else {
         } else {
@@ -734,8 +734,8 @@ public class FileDisplayActivity extends HookActivity implements
             }
             }
         }
         }
 
 
-        Intent i = new Intent(this, FileUploadService.class);
-        i.putExtra(FileUploadService.KEY_ACCOUNT,
+        Intent i = new Intent(this, FileUploader.class);
+        i.putExtra(FileUploader.KEY_ACCOUNT,
                 getAccount());
                 getAccount());
         OCFile currentDir = getCurrentDir();
         OCFile currentDir = getCurrentDir();
         String remotePath =  (currentDir != null) ? currentDir.getRemotePath() : OCFile.ROOT_PATH;
         String remotePath =  (currentDir != null) ? currentDir.getRemotePath() : OCFile.ROOT_PATH;
@@ -762,17 +762,17 @@ public class FileDisplayActivity extends HookActivity implements
             remotePath += new File(filePath).getName();
             remotePath += new File(filePath).getName();
         }
         }
 
 
-        i.putExtra(FileUploadService.KEY_LOCAL_FILE, filePath);
-        i.putExtra(FileUploadService.KEY_REMOTE_FILE, remotePath);
-        i.putExtra(FileUploadService.KEY_MIME_TYPE, mimeType);
-        i.putExtra(FileUploadService.KEY_UPLOAD_TYPE,
-                FileUploadService.UPLOAD_SINGLE_FILE);
+        i.putExtra(FileUploader.KEY_LOCAL_FILE, filePath);
+        i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePath);
+        i.putExtra(FileUploader.KEY_MIME_TYPE, mimeType);
+        i.putExtra(FileUploader.KEY_UPLOAD_TYPE,
+                FileUploader.UPLOAD_SINGLE_FILE);
         if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE) {
         if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE) {
-            i.putExtra(FileUploadService.KEY_LOCAL_BEHAVIOUR,
-                    FileUploadService.LOCAL_BEHAVIOUR_MOVE);
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR,
+                    FileUploader.LOCAL_BEHAVIOUR_MOVE);
         }
         }
         if(startService(i) == null) {
         if(startService(i) == null) {
-            Log_OC.e(TAG, "FileUploadService could not be started");
+            Log_OC.e(TAG, "FileUploader could not be started");
         }
         }
 
 
     }
     }
@@ -861,7 +861,7 @@ public class FileDisplayActivity extends HookActivity implements
         // syncIntentFilter);
         // syncIntentFilter);
 
 
         // Listen for upload messages
         // Listen for upload messages
-        IntentFilter uploadIntentFilter = new IntentFilter(FileUploadService.getUploadFinishMessage());
+        IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.getUploadFinishMessage());
         mUploadFinishReceiver = new UploadFinishReceiver();
         mUploadFinishReceiver = new UploadFinishReceiver();
         registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
         registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
 
 
@@ -1038,8 +1038,8 @@ public class FileDisplayActivity extends HookActivity implements
         @Override
         @Override
         public void onReceive(Context context, Intent intent) {
         public void onReceive(Context context, Intent intent) {
             try {
             try {
-                String uploadedRemotePath = intent.getStringExtra(FileUploadService.EXTRA_REMOTE_PATH);
-                String accountName = intent.getStringExtra(FileUploadService.ACCOUNT_NAME);
+                String uploadedRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH);
+                String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
                 boolean sameAccount = getAccount() != null && accountName.equals(getAccount().name);
                 boolean sameAccount = getAccount() != null && accountName.equals(getAccount().name);
                 OCFile currentDir = getCurrentDir();
                 OCFile currentDir = getCurrentDir();
                 boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) &&
                 boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) &&
@@ -1047,17 +1047,17 @@ public class FileDisplayActivity extends HookActivity implements
 
 
                 if (sameAccount && isDescendant) {
                 if (sameAccount && isDescendant) {
                     String linkedToRemotePath =
                     String linkedToRemotePath =
-                            intent.getStringExtra(FileUploadService.EXTRA_LINKED_TO_PATH);
+                            intent.getStringExtra(FileUploader.EXTRA_LINKED_TO_PATH);
                     if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
                     if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
                         refreshListOfFilesFragment();
                         refreshListOfFilesFragment();
                     }
                     }
                 }
                 }
 
 
                 boolean uploadWasFine = intent.getBooleanExtra(
                 boolean uploadWasFine = intent.getBooleanExtra(
-                        FileUploadService.EXTRA_UPLOAD_RESULT,
+                        FileUploader.EXTRA_UPLOAD_RESULT,
                         false);
                         false);
                 boolean renamedInUpload = getFile().getRemotePath().
                 boolean renamedInUpload = getFile().getRemotePath().
-                        equals(intent.getStringExtra(FileUploadService.EXTRA_OLD_REMOTE_PATH));
+                        equals(intent.getStringExtra(FileUploader.EXTRA_OLD_REMOTE_PATH));
 
 
                 boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) ||
                 boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) ||
                         renamedInUpload;
                         renamedInUpload;
@@ -1269,7 +1269,7 @@ public class FileDisplayActivity extends HookActivity implements
                     }
                     }
 
 
             } else if (component.equals(new ComponentName(FileDisplayActivity.this,
             } else if (component.equals(new ComponentName(FileDisplayActivity.this,
-                    FileUploadService.class))) {
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service connected");
                 Log_OC.d(TAG, "Upload service connected");
                 mUploaderBinder = (FileUploaderBinder) service;
                 mUploaderBinder = (FileUploaderBinder) service;
             } else {
             } else {
@@ -1298,7 +1298,7 @@ public class FileDisplayActivity extends HookActivity implements
                 Log_OC.d(TAG, "Download service disconnected");
                 Log_OC.d(TAG, "Download service disconnected");
                 mDownloaderBinder = null;
                 mDownloaderBinder = null;
             } else if (component.equals(new ComponentName(FileDisplayActivity.this,
             } else if (component.equals(new ComponentName(FileDisplayActivity.this,
-                    FileUploadService.class))) {
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service disconnected");
                 Log_OC.d(TAG, "Upload service disconnected");
                 mUploaderBinder = null;
                 mUploaderBinder = null;
             }
             }

+ 7 - 8
src/com/owncloud/android/ui/activity/Preferences.java

@@ -74,10 +74,9 @@ import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.files.FileOperationsHelper;
 import com.owncloud.android.files.FileOperationsHelper;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.ui.RadioButtonPreference;
 import com.owncloud.android.ui.RadioButtonPreference;
@@ -121,7 +120,7 @@ public class Preferences extends PreferenceActivity
     private String mUploadVideoPath;
     private String mUploadVideoPath;
 
 
     protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
     protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
-    protected FileUploadService.FileUploaderBinder mUploaderBinder = null;
+    protected FileUploader.FileUploaderBinder mUploaderBinder = null;
     private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
     private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
 
 
 
 
@@ -473,7 +472,7 @@ public class Preferences extends PreferenceActivity
         }
         }
         mUploadServiceConnection = newTransferenceServiceConnection();
         mUploadServiceConnection = newTransferenceServiceConnection();
         if (mUploadServiceConnection != null) {
         if (mUploadServiceConnection != null) {
-            bindService(new Intent(this, FileUploadService.class), mUploadServiceConnection,
+            bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
                     Context.BIND_AUTO_CREATE);
                     Context.BIND_AUTO_CREATE);
         }
         }
 
 
@@ -883,7 +882,7 @@ public class Preferences extends PreferenceActivity
 
 
 
 
     @Override
     @Override
-    public FileUploadService.FileUploaderBinder getFileUploaderBinder() {
+    public FileUploader.FileUploaderBinder getFileUploaderBinder() {
         return mUploaderBinder;
         return mUploaderBinder;
     }
     }
 
 
@@ -916,9 +915,9 @@ public class Preferences extends PreferenceActivity
                 mDownloaderBinder = (FileDownloader.FileDownloaderBinder) service;
                 mDownloaderBinder = (FileDownloader.FileDownloaderBinder) service;
 
 
             } else if (component.equals(new ComponentName(Preferences.this,
             } else if (component.equals(new ComponentName(Preferences.this,
-                    FileUploadService.class))) {
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service connected");
                 Log_OC.d(TAG, "Upload service connected");
-                mUploaderBinder = (FileUploadService.FileUploaderBinder) service;
+                mUploaderBinder = (FileUploader.FileUploaderBinder) service;
             } else {
             } else {
                 return;
                 return;
             }
             }
@@ -931,7 +930,7 @@ public class Preferences extends PreferenceActivity
                 Log_OC.d(TAG, "Download service suddenly disconnected");
                 Log_OC.d(TAG, "Download service suddenly disconnected");
                 mDownloaderBinder = null;
                 mDownloaderBinder = null;
             } else if (component.equals(new ComponentName(Preferences.this,
             } else if (component.equals(new ComponentName(Preferences.this,
-                    FileUploadService.class))) {
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service suddenly disconnected");
                 Log_OC.d(TAG, "Upload service suddenly disconnected");
                 mUploaderBinder = null;
                 mUploaderBinder = null;
             }
             }

+ 7 - 7
src/com/owncloud/android/ui/activity/UploadListActivity.java

@@ -40,8 +40,8 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.OCUpload;
-import com.owncloud.android.files.services.FileUploadService;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.fragment.UploadListFragment;
 import com.owncloud.android.ui.fragment.UploadListFragment;
 import com.owncloud.android.ui.preview.PreviewImageActivity;
 import com.owncloud.android.ui.preview.PreviewImageActivity;
@@ -98,8 +98,8 @@ public class UploadListActivity extends FileActivity implements UploadListFragme
         // Listen for upload messages
         // Listen for upload messages
         mUploadMessagesReceiver = new UploadMessagesReceiver();
         mUploadMessagesReceiver = new UploadMessagesReceiver();
         IntentFilter uploadIntentFilter = new IntentFilter();
         IntentFilter uploadIntentFilter = new IntentFilter();
-        uploadIntentFilter.addAction(FileUploadService.getUploadStartMessage());
-        uploadIntentFilter.addAction(FileUploadService.getUploadFinishMessage());
+        uploadIntentFilter.addAction(FileUploader.getUploadStartMessage());
+        uploadIntentFilter.addAction(FileUploader.getUploadFinishMessage());
         registerReceiver(mUploadMessagesReceiver, uploadIntentFilter);
         registerReceiver(mUploadMessagesReceiver, uploadIntentFilter);
 
 
         Log_OC.v(TAG, "onResume() end");
         Log_OC.v(TAG, "onResume() end");
@@ -199,8 +199,8 @@ public class UploadListActivity extends FileActivity implements UploadListFragme
                 }
                 }
                 break;
                 break;
 //            case R.id.action_retry_uploads:
 //            case R.id.action_retry_uploads:
-//                Log_OC.d(TAG, "FileUploadService.retry() called by onMenuItemSelected()");
-//                FileUploadService.retry(this);
+//                Log_OC.d(TAG, "FileUploader.retry() called by onMenuItemSelected()");
+//                FileUploader.retry(this);
 //                break;
 //                break;
 
 
             case R.id.action_clear_failed_uploads:
             case R.id.action_clear_failed_uploads:
@@ -271,7 +271,7 @@ public class UploadListActivity extends FileActivity implements UploadListFragme
 
 
         @Override
         @Override
         public void onServiceDisconnected(ComponentName component) {
         public void onServiceDisconnected(ComponentName component) {
-            if (component.equals(new ComponentName(UploadListActivity.this, FileUploadService.class))) {
+            if (component.equals(new ComponentName(UploadListActivity.this, FileUploader.class))) {
                 Log_OC.d(TAG, "UploadListActivity suddenly disconnected from Upload service");
                 Log_OC.d(TAG, "UploadListActivity suddenly disconnected from Upload service");
                 mUploaderBinder = null;
                 mUploaderBinder = null;
             }
             }

+ 13 - 13
src/com/owncloud/android/ui/activity/Uploader.java

@@ -69,7 +69,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountAuthenticator;
 import com.owncloud.android.authentication.AccountAuthenticator;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
@@ -567,14 +567,14 @@ public class Uploader extends FileActivity
                     throw new SecurityException();
                     throw new SecurityException();
                 }
                 }
 
 
-                Intent intent = new Intent(getApplicationContext(), FileUploadService.class);
-                intent.putExtra(FileUploadService.KEY_UPLOAD_TYPE,
-                        FileUploadService.UPLOAD_MULTIPLE_FILES);
-                intent.putExtra(FileUploadService.KEY_LOCAL_FILE,
+                Intent intent = new Intent(getApplicationContext(), FileUploader.class);
+                intent.putExtra(FileUploader.KEY_UPLOAD_TYPE,
+                        FileUploader.UPLOAD_MULTIPLE_FILES);
+                intent.putExtra(FileUploader.KEY_LOCAL_FILE,
                         local.toArray(new String[local.size()]));
                         local.toArray(new String[local.size()]));
-                intent.putExtra(FileUploadService.KEY_REMOTE_FILE,
+                intent.putExtra(FileUploader.KEY_REMOTE_FILE,
                         remote.toArray(new String[remote.size()]));
                         remote.toArray(new String[remote.size()]));
-                intent.putExtra(FileUploadService.KEY_ACCOUNT, getAccount());
+                intent.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
                 startService(intent);
                 startService(intent);
 
 
                 //Save the path to shared preferences
                 //Save the path to shared preferences
@@ -703,12 +703,12 @@ public class Uploader extends FileActivity
             dismissWaitingCopyDialog();
             dismissWaitingCopyDialog();
         }
         }
         if (result != null) {
         if (result != null) {
-            Intent intent = new Intent(getApplicationContext(), FileUploadService.class);
-            intent.putExtra(FileUploadService.KEY_UPLOAD_TYPE,
-                    FileUploadService.UPLOAD_SINGLE_FILE);
-            intent.putExtra(FileUploadService.KEY_LOCAL_FILE, result);
-            intent.putExtra(FileUploadService.KEY_REMOTE_FILE, mRemoteCacheData.get(index));
-            intent.putExtra(FileUploadService.KEY_ACCOUNT, getAccount());
+            Intent intent = new Intent(getApplicationContext(), FileUploader.class);
+            intent.putExtra(FileUploader.KEY_UPLOAD_TYPE,
+                    FileUploader.UPLOAD_SINGLE_FILE);
+            intent.putExtra(FileUploader.KEY_LOCAL_FILE, result);
+            intent.putExtra(FileUploader.KEY_REMOTE_FILE, mRemoteCacheData.get(index));
+            intent.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
             startService(intent);
             startService(intent);
 
 
         } else {
         } else {

+ 5 - 5
src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java

@@ -44,7 +44,7 @@ import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
 import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.db.UploadResult;
 import com.owncloud.android.db.UploadResult;
-import com.owncloud.android.files.services.FileUploadService;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.operations.UploadFileOperation;
 import com.owncloud.android.operations.UploadFileOperation;
@@ -241,7 +241,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
                     mProgressListener = new ProgressListener(progressBar);
                     mProgressListener = new ProgressListener(progressBar);
                     if(mParentActivity.getFileUploaderBinder() != null) {
                     if(mParentActivity.getFileUploaderBinder() != null) {
                         mParentActivity.getFileUploaderBinder().addDatatransferProgressListener(mProgressListener,
                         mParentActivity.getFileUploaderBinder().addDatatransferProgressListener(mProgressListener,
-                                mParentActivity.getAccount(), uploadOCFile, upload.getUploadId());
+                                mParentActivity.getAccount(), uploadOCFile /*, upload.getUploadId() */);
                     } else {
                     } else {
                         Log_OC.e(TAG, "UploadBinder == null. It should have been created on creating mParentActivity"
                         Log_OC.e(TAG, "UploadBinder == null. It should have been created on creating mParentActivity"
                                 + " which inherits from FileActivity. Fix that!");
                                 + " which inherits from FileActivity. Fix that!");
@@ -306,7 +306,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
                     } else {
                     } else {
                         status = mParentActivity.getString(R.string.uploads_view_upload_status_failed_retry);
                         status = mParentActivity.getString(R.string.uploads_view_upload_status_failed_retry);
                     }
                     }
-                    String laterReason = FileUploadService.getUploadLaterReason(mParentActivity, upload);
+                    String laterReason = upload.getUploadLaterReason(mParentActivity);
                     if(laterReason != null) {
                     if(laterReason != null) {
                         //Upload failed once but is delayed now, show reason.
                         //Upload failed once but is delayed now, show reason.
                         status = laterReason;
                         status = laterReason;
@@ -321,7 +321,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
                     pathTextView.setVisibility(View.GONE);
                     pathTextView.setVisibility(View.GONE);
                     fileSizeTextView.setVisibility(View.GONE);
                     fileSizeTextView.setVisibility(View.GONE);
                     accountNameTextView.setVisibility(View.INVISIBLE);
                     accountNameTextView.setVisibility(View.INVISIBLE);
-                    status = FileUploadService.getUploadLaterReason(mParentActivity, upload);
+                    status = upload.getUploadLaterReason(mParentActivity);
                     break;
                     break;
                 case UPLOAD_SUCCEEDED:
                 case UPLOAD_SUCCEEDED:
                     status =  mParentActivity.getString(R.string.uploads_view_upload_status_succeeded);
                     status =  mParentActivity.getString(R.string.uploads_view_upload_status_succeeded);
@@ -347,7 +347,7 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
                         && mCurrentUpload != null) {
                         && mCurrentUpload != null) {
                     OCFile currentOcFile = mCurrentUpload.getFile();
                     OCFile currentOcFile = mCurrentUpload.getFile();
                     mParentActivity.getFileUploaderBinder().removeDatatransferProgressListener(mProgressListener,
                     mParentActivity.getFileUploaderBinder().removeDatatransferProgressListener(mProgressListener,
-                            upload.getAccount(mParentActivity), currentOcFile, upload.getUploadId());
+                            upload.getAccount(mParentActivity), currentOcFile /*, upload.getUploadId() */);
                     mProgressListener = null;
                     mProgressListener = null;
                     mCurrentUpload = null;
                     mCurrentUpload = null;
                 }
                 }

+ 1 - 1
src/com/owncloud/android/ui/adapter/FileListListAdapter.java

@@ -47,7 +47,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.DisplayUtils;

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

@@ -43,7 +43,7 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileActivity;
@@ -547,7 +547,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
             }
             }
             if (mContainerActivity.getFileUploaderBinder() != null) {
             if (mContainerActivity.getFileUploaderBinder() != null) {
                 mContainerActivity.getFileUploaderBinder().
                 mContainerActivity.getFileUploaderBinder().
-                        addDatatransferProgressListener(mProgressListener, mAccount, getFile(), 0);
+                        addDatatransferProgressListener(mProgressListener, mAccount, getFile()/*, 0*/);
             }
             }
         } else {
         } else {
             Log_OC.d(TAG, "mProgressListener == null");
             Log_OC.d(TAG, "mProgressListener == null");
@@ -563,7 +563,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
             }
             }
             if (mContainerActivity.getFileUploaderBinder() != null) {
             if (mContainerActivity.getFileUploaderBinder() != null) {
                 mContainerActivity.getFileUploaderBinder().
                 mContainerActivity.getFileUploaderBinder().
-                        removeDatatransferProgressListener(mProgressListener, mAccount, getFile(), 0);
+                        removeDatatransferProgressListener(mProgressListener, mAccount, getFile()/*, 0*/);
             }
             }
         }
         }
     }
     }

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

@@ -26,7 +26,7 @@ import android.support.v4.app.Fragment;
 
 
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.ui.activity.ComponentsGetter;
 
 
 
 

+ 4 - 5
src/com/owncloud/android/ui/preview/PreviewImageActivity.java

@@ -32,7 +32,6 @@ import android.os.Handler;
 import android.os.IBinder;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Message;
 import android.os.Parcelable;
 import android.os.Parcelable;
-import android.preference.PreferenceManager;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewPager;
 import android.support.v4.view.ViewPager;
 import android.support.v4.widget.DrawerLayout;
 import android.support.v4.widget.DrawerLayout;
@@ -48,8 +47,8 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileUploadService;
-import com.owncloud.android.files.services.FileUploadService.FileUploaderBinder;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
 import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -265,7 +264,7 @@ public class PreviewImageActivity extends FileActivity implements
                 }
                 }
 
 
             } else if (component.equals(new ComponentName(PreviewImageActivity.this,
             } else if (component.equals(new ComponentName(PreviewImageActivity.this,
-                    FileUploadService.class))) {
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service connected");
                 Log_OC.d(TAG, "Upload service connected");
                 mUploaderBinder = (FileUploaderBinder) service;
                 mUploaderBinder = (FileUploaderBinder) service;
             } else {
             } else {
@@ -281,7 +280,7 @@ public class PreviewImageActivity extends FileActivity implements
                 Log_OC.d(TAG, "Download service suddenly disconnected");
                 Log_OC.d(TAG, "Download service suddenly disconnected");
                 mDownloaderBinder = null;
                 mDownloaderBinder = null;
             } else if (component.equals(new ComponentName(PreviewImageActivity.this,
             } else if (component.equals(new ComponentName(PreviewImageActivity.this,
-                    FileUploadService.class))) {
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service suddenly disconnected");
                 Log_OC.d(TAG, "Upload service suddenly disconnected");
                 mUploaderBinder = null;
                 mUploaderBinder = null;
             }
             }