Ver Fonte

Rebase master

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk há 1 ano atrás
pai
commit
5936210a30

+ 4 - 4
app/src/androidTest/java/com/owncloud/android/files/FileMenuFilterIT.kt

@@ -23,7 +23,8 @@ package com.owncloud.android.files
 import androidx.test.core.app.launchActivity
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.nextcloud.client.account.User
-import com.nextcloud.client.files.downloader.FileDownloadWorker
+import com.nextcloud.client.files.download.FileDownloadWorker
+import com.nextcloud.client.files.upload.FileUploadHelper
 import com.nextcloud.test.TestActivity
 import com.nextcloud.utils.EditorUtils
 import com.owncloud.android.AbstractIT
@@ -31,7 +32,6 @@ import com.owncloud.android.R
 import com.owncloud.android.datamodel.ArbitraryDataProvider
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
-import com.owncloud.android.files.services.FileUploader
 import com.owncloud.android.lib.resources.files.model.FileLockType
 import com.owncloud.android.lib.resources.status.CapabilityBooleanType
 import com.owncloud.android.lib.resources.status.OCCapability
@@ -59,7 +59,7 @@ class FileMenuFilterIT : AbstractIT() {
     private lateinit var mockStorageManager: FileDataStorageManager
 
     @MockK
-    private lateinit var mockFileUploaderBinder: FileUploader.FileUploaderBinder
+    private lateinit var mockFileUploaderBinder: FileUploadHelper
 
     @MockK
     private lateinit var mockFileDownloadProgressListener: FileDownloadWorker.FileDownloadProgressListener
@@ -76,7 +76,7 @@ class FileMenuFilterIT : AbstractIT() {
     fun setup() {
         MockKAnnotations.init(this)
         every { mockFileUploaderBinder.isUploading(any(), any()) } returns false
-        every { mockComponentsGetter.fileUploaderBinder } returns mockFileUploaderBinder
+        every { mockComponentsGetter.fileUploaderHelper } returns mockFileUploaderBinder
         every { mockFileDownloadProgressListener.isDownloading(any(), any()) } returns false
         every { mockComponentsGetter.fileDownloadProgressListener } returns mockFileDownloadProgressListener
         every { mockOperationsServiceBinder.isSynchronizing(any(), any()) } returns false

+ 3 - 3
app/src/debug/java/com/nextcloud/test/TestActivity.kt

@@ -25,7 +25,8 @@ import android.os.Bundle
 import android.view.View
 import androidx.fragment.app.Fragment
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
-import com.nextcloud.client.files.downloader.FileDownloadWorker
+import com.nextcloud.client.jobs.download.FileDownloadWorker
+import com.nextcloud.client.jobs.upload.FileUploadHelper
 import com.nextcloud.client.network.Connectivity
 import com.nextcloud.client.network.ConnectivityService
 import com.nextcloud.utils.EditorUtils
@@ -34,7 +35,6 @@ import com.owncloud.android.databinding.TestLayoutBinding
 import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
-import com.owncloud.android.files.services.FileUploader
 import com.owncloud.android.lib.resources.status.OCCapability
 import com.owncloud.android.lib.resources.status.OwnCloudVersion
 import com.owncloud.android.services.OperationsService
@@ -126,7 +126,7 @@ class TestActivity :
         TODO("Not yet implemented")
     }
 
-    override fun getFileUploaderBinder(): FileUploader.FileUploaderBinder? {
+    override fun getFileUploaderHelper(): FileUploadHelper? {
         return null
     }
 

+ 3 - 2
app/src/main/java/com/owncloud/android/db/OCUpload.java

@@ -35,6 +35,7 @@ import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.files.services.NameCollisionPolicy;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.operations.UploadFileOperation;
+import com.owncloud.android.utils.FilesUploadHelper;
 import com.owncloud.android.utils.MimeTypeUtil;
 
 import java.io.File;
@@ -183,9 +184,9 @@ public class OCUpload implements Parcelable {
         folderUnlockToken = "";
     }
 
-    public void setDataFixed(FileUploader.FileUploaderBinder binder) {
+    public void setDataFixed(FilesUploadHelper uploadHelper) {
         fixedUploadStatus = uploadStatus;
-        fixedUploadingNow = binder != null && binder.isUploadingNow(this);
+        fixedUploadingNow = uploadHelper != null && uploadHelper.isUploadingNow(this);
         fixedUploadEndTimeStamp = uploadEndTimestamp;
         fixedUploadId = uploadId;
     }

+ 7 - 7
app/src/main/java/com/owncloud/android/ui/activity/ComponentsGetter.java

@@ -20,9 +20,9 @@
 
 package com.owncloud.android.ui.activity;
 
-import com.nextcloud.client.files.downloader.FileDownloadWorker;
+import com.nextcloud.client.jobs.download.FileDownloadWorker;
+import com.nextcloud.client.jobs.upload.FileUploadHelper;
 import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.helpers.FileOperationsHelper;
 
@@ -39,18 +39,18 @@ public interface ComponentsGetter {
      * To be invoked when the parent activity is fully created to get a reference
      * to the FileUploader service API.
      */
-    public FileUploaderBinder getFileUploaderBinder();
+    public FileUploadHelper getFileUploaderHelper();
+
 
-    
     /**
      * To be invoked when the parent activity is fully created to get a reference
-     * to the OperationsSerivce service API.
+     * to the OperationsService service API.
      */
     public OperationsServiceBinder getOperationsServiceBinder();
 
-    
+
     public FileDataStorageManager getStorageManager();
-    
+
     public FileOperationsHelper getFileOperationsHelper();
 
 

+ 19 - 32
app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java

@@ -43,9 +43,9 @@ import android.text.TextUtils;
 import com.google.android.material.snackbar.Snackbar;
 import com.nextcloud.client.account.User;
 import com.nextcloud.client.account.UserAccountManager;
-import com.nextcloud.client.files.downloader.FileDownloadHelper;
-import com.nextcloud.client.files.downloader.FileDownloadWorker;
 import com.nextcloud.client.jobs.BackgroundJobManager;
+import com.nextcloud.client.jobs.download.FileDownloadWorker;
+import com.nextcloud.client.jobs.upload.FileUploadHelper;
 import com.nextcloud.client.network.ConnectivityService;
 import com.nextcloud.utils.EditorUtils;
 import com.nextcloud.utils.extensions.BundleExtensionsKt;
@@ -56,8 +56,6 @@ import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.OCFile;
-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.OwnCloudClient;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
@@ -123,8 +121,8 @@ import static com.owncloud.android.ui.activity.FileDisplayActivity.TAG_PUBLIC_LI
  * Activity with common behaviour for activities handling {@link OCFile}s in ownCloud {@link Account}s .
  */
 public abstract class FileActivity extends DrawerActivity
-        implements OnRemoteOperationListener, ComponentsGetter, SslUntrustedCertDialog.OnSslUntrustedCertListener,
-        LoadingVersionNumberTask.VersionDevInterface, FileDetailSharingFragment.OnEditShareListener {
+    implements OnRemoteOperationListener, ComponentsGetter, SslUntrustedCertDialog.OnSslUntrustedCertListener,
+    LoadingVersionNumberTask.VersionDevInterface, FileDetailSharingFragment.OnEditShareListener {
 
     public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE";
     public static final String EXTRA_LIVE_PHOTO_FILE = "com.owncloud.android.ui.activity.LIVE.PHOTO.FILE";
@@ -150,7 +148,7 @@ public abstract class FileActivity extends DrawerActivity
     private static final String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT";
     private static final String DIALOG_CERT_NOT_SAVED = "DIALOG_CERT_NOT_SAVED";
 
-     /** Main {@link OCFile} handled by the activity.*/
+    /** Main {@link OCFile} handled by the activity.*/
     private OCFile mFile;
 
     /** Flag to signal if the activity is launched by a notification */
@@ -168,8 +166,7 @@ public abstract class FileActivity extends DrawerActivity
     private boolean mResumed;
 
     protected FileDownloadWorker.FileDownloadProgressListener fileDownloadProgressListener;
-    protected FileUploaderBinder mUploaderBinder;
-    private ServiceConnection mUploadServiceConnection;
+    protected FileUploadHelper fileUploadHelper = FileUploadHelper.Companion.instance();
 
     @Inject
     UserAccountManager accountManager;
@@ -229,7 +226,7 @@ public abstract class FileActivity extends DrawerActivity
             user = IntentExtensionsKt.getParcelableArgument(getIntent(), FileActivity.EXTRA_USER, User.class);
             mFile = IntentExtensionsKt.getParcelableArgument(getIntent(), FileActivity.EXTRA_FILE, OCFile.class);
             mFromNotification = getIntent().getBooleanExtra(FileActivity.EXTRA_FROM_NOTIFICATION,
-                    false);
+                                                            false);
 
             if (user != null) {
                 setUser(user);
@@ -238,13 +235,7 @@ public abstract class FileActivity extends DrawerActivity
 
         mOperationsServiceConnection = new OperationsServiceConnection();
         bindService(new Intent(this, OperationsService.class), mOperationsServiceConnection,
-                Context.BIND_AUTO_CREATE);
-
-        mUploadServiceConnection = newTransferenceServiceConnection();
-        if (mUploadServiceConnection != null) {
-            bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
                     Context.BIND_AUTO_CREATE);
-        }
     }
 
     public void checkInternetConnection() {
@@ -283,10 +274,6 @@ public abstract class FileActivity extends DrawerActivity
             unbindService(mOperationsServiceConnection);
             mOperationsServiceBinder = null;
         }
-        if (mUploadServiceConnection != null) {
-            unbindService(mUploadServiceConnection);
-            mUploadServiceConnection = null;
-        }
 
         super.onDestroy();
     }
@@ -365,7 +352,7 @@ public abstract class FileActivity extends DrawerActivity
         dismissLoadingDialog();
 
         if (!result.isSuccess() && (
-                result.getCode() == ResultCode.UNAUTHORIZED ||
+            result.getCode() == ResultCode.UNAUTHORIZED ||
                 (result.isException() && result.getException() instanceof AuthenticatorException)
         )) {
 
@@ -393,8 +380,8 @@ public abstract class FileActivity extends DrawerActivity
 
             } else if (result.getCode() != ResultCode.CANCELLED) {
                 DisplayUtils.showSnackMessage(
-                        this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources())
-                );
+                    this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources())
+                                             );
             }
 
         } else if (operation instanceof SynchronizeFileOperation) {
@@ -525,7 +512,7 @@ public abstract class FileActivity extends DrawerActivity
         } else {
             if (!operation.transferWasRequested()) {
                 DisplayUtils.showSnackMessage(this, ErrorMessageAdapter.getErrorCauseMessage(result,
-                        operation, getResources()));
+                                                                                             operation, getResources()));
             }
             supportInvalidateOptionsMenu();
         }
@@ -575,7 +562,7 @@ public abstract class FileActivity extends DrawerActivity
         long waitingForOpId = mFileOperationsHelper.getOpIdWaitingFor();
         if (waitingForOpId <= Integer.MAX_VALUE) {
             boolean wait = mOperationsServiceBinder.dispatchResultIfFinished((int)waitingForOpId,
-                    this);
+                                                                             this);
             if (!wait ) {
                 dismissLoadingDialog();
             }
@@ -620,8 +607,8 @@ public abstract class FileActivity extends DrawerActivity
     }
 
     @Override
-    public FileUploaderBinder getFileUploaderBinder() {
-        return mUploaderBinder;
+    public FileUploadHelper getFileUploaderHelper() {
+        return fileUploadHelper;
     }
 
     public OCFile getCurrentDir() {
@@ -648,7 +635,7 @@ public abstract class FileActivity extends DrawerActivity
     public void onFailedSavingCertificate() {
         ConfirmationDialogFragment dialog = ConfirmationDialogFragment.newInstance(
             R.string.ssl_validator_not_saved, new String[]{}, 0, R.string.common_ok, -1, -1
-        );
+                                                                                  );
         dialog.show(getSupportFragmentManager(), DIALOG_CERT_NOT_SAVED);
     }
 
@@ -694,10 +681,10 @@ public abstract class FileActivity extends DrawerActivity
                 DisplayUtils.startLinkIntent(activity, devApkLink);
             } else {
                 Snackbar.make(activity.findViewById(android.R.id.content), R.string.dev_version_new_version_available,
-                        Snackbar.LENGTH_LONG)
-                        .setAction(activity.getString(R.string.version_dev_download), v -> {
-                            DisplayUtils.startLinkIntent(activity, devApkLink);
-                        }).show();
+                              Snackbar.LENGTH_LONG)
+                    .setAction(activity.getString(R.string.version_dev_download), v -> {
+                        DisplayUtils.startLinkIntent(activity, devApkLink);
+                    }).show();
             }
         } else {
             if (!inBackground) {

+ 3 - 61
app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -28,21 +28,18 @@ import android.accounts.AccountManager;
 import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
 import android.accounts.OperationCanceledException;
-import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.view.MenuItem;
 import android.view.View;
 
 import com.google.common.collect.Sets;
 import com.nextcloud.client.account.User;
 import com.nextcloud.client.account.UserAccountManager;
-import com.nextcloud.client.files.downloader.FileDownloadHelper;
 import com.nextcloud.client.jobs.BackgroundJobManager;
+import com.nextcloud.client.jobs.download.FileDownloadHelper;
 import com.nextcloud.client.onboarding.FirstRunActivity;
 import com.nextcloud.java.util.Optional;
 import com.nextcloud.model.WorkerState;
@@ -54,7 +51,6 @@ import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.UserInfo;
 import com.owncloud.android.lib.common.utils.Log_OC;
@@ -164,11 +160,9 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
 
         recyclerView.setAdapter(userListAdapter);
         recyclerView.setLayoutManager(new LinearLayoutManager(this));
-        initializeComponentGetters();
         observeWorkerState();
     }
 
-
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
@@ -243,17 +237,6 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         }
     }
 
-    /**
-     * Initialize ComponentsGetters.
-     */
-    private void initializeComponentGetters() {
-        uploadServiceConnection = newTransferenceServiceConnection();
-        if (uploadServiceConnection != null) {
-            bindService(new Intent(this, FileUploader.class), uploadServiceConnection,
-                        Context.BIND_AUTO_CREATE);
-        }
-    }
-
     private List<UserListItem> getUserListItems() {
         List<User> users = accountManager.getAllUsers();
         List<UserListItem> userListItems = new ArrayList<>(users.size());
@@ -337,11 +320,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
             // after remove account
             Optional<User> user = accountManager.getUser(accountName);
             if (!user.isPresent()) {
-                // Cancel transfers of the removed account
-                if (mUploaderBinder != null) {
-                    mUploaderBinder.cancel(accountName);
-                }
-
+                fileUploadHelper.cancel(accountName);
                 FileDownloadHelper.Companion.instance().cancelAllDownloadsForAccount(workerAccountName, workerCurrentDownload);
             }
 
@@ -386,11 +365,6 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         return handler;
     }
 
-    @Override
-    public FileUploader.FileUploaderBinder getFileUploaderBinder() {
-        return mUploaderBinder;
-    }
-
     @Override
     public OperationsService.OperationsServiceBinder getOperationsServiceBinder() {
         return null;
@@ -406,10 +380,6 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         return null;
     }
 
-    protected ServiceConnection newTransferenceServiceConnection() {
-        return new ManageAccountsServiceConnection();
-    }
-
     private void performAccountRemoval(User user) {
         // disable account in recycler view
         for (int i = 0; i < userListAdapter.getItemCount(); i++) {
@@ -427,13 +397,8 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
         arbitraryDataProvider.storeOrUpdateKeyValue(user.getAccountName(), PENDING_FOR_REMOVAL, String.valueOf(true));
 
-        // Cancel transfers
-        if (mUploaderBinder != null) {
-            mUploaderBinder.cancel(user);
-        }
-
         FileDownloadHelper.Companion.instance().cancelAllDownloadsForAccount(workerAccountName, workerCurrentDownload);
-
+        fileUploadHelper.cancel(user.getAccountName());
         backgroundJobManager.startAccountRemovalJob(user.getAccountName(), false);
 
         // immediately select a new account
@@ -531,27 +496,4 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
     public void onAccountClicked(User user) {
         openAccount(user);
     }
-
-    /**
-     * Defines callbacks for service binding, passed to bindService()
-     */
-    private class ManageAccountsServiceConnection implements ServiceConnection {
-
-        @Override
-        public void onServiceConnected(ComponentName component, IBinder service) {
-            if (component.equals(new ComponentName(ManageAccountsActivity.this, FileUploader.class))) {
-                Log_OC.d(TAG, "Upload service connected");
-                mUploaderBinder = (FileUploader.FileUploaderBinder) service;
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName component) {
-            if (component.equals(new ComponentName(ManageAccountsActivity.this, FileUploader.class))) {
-                Log_OC.d(TAG, "Upload service suddenly disconnected");
-                mUploaderBinder = null;
-            }
-        }
-    }
-
 }

+ 17 - 21
app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java

@@ -68,6 +68,7 @@ import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.notifications.NotificationUtils;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.FilesUploadHelper;
 import com.owncloud.android.utils.MimeTypeUtil;
 import com.owncloud.android.utils.theme.ViewThemeUtils;
 
@@ -126,10 +127,10 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
         headerViewHolder.binding.uploadListAction.setOnClickListener(v -> {
             switch (group.type) {
                 case CURRENT -> {
-                    FileUploader.FileUploaderBinder uploaderBinder = parentActivity.getFileUploaderBinder();
-                    if (uploaderBinder != null) {
+                    FilesUploadHelper uploadHelper = parentActivity.getFileUploaderHelper();
+                    if (uploadHelper != null) {
                         for (OCUpload upload : group.getItems()) {
-                            uploaderBinder.cancel(upload);
+                            uploadHelper.cancel(upload);
                         }
                     }
                 }
@@ -270,27 +271,22 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
                 viewThemeUtils.platform.themeHorizontalProgressBar(itemViewHolder.binding.uploadProgressBar);
                 itemViewHolder.binding.uploadProgressBar.setProgress(0);
                 itemViewHolder.binding.uploadProgressBar.setVisibility(View.VISIBLE);
-                FileUploader.FileUploaderBinder binder = parentActivity.getFileUploaderBinder();
-                if (binder != null) {
-                    if (binder.isUploadingNow(item)) {
+                FilesUploadHelper uploadHelper = parentActivity.getFileUploaderHelper();
+                if (uploadHelper != null) {
+                    if (uploadHelper.isUploadingNow(item)) {
                         // really uploading, so...
                         // ... unbind the old progress bar, if any; ...
                         if (progressListener != null) {
-                            binder.removeDatatransferProgressListener(
-                                progressListener,
-                                progressListener.getUpload()   // the one that was added
-                                                                     );
+                            uploadHelper.removeDatatransferProgressListener(progressListener, progressListener.getUpload());
                         }
                         // ... then, bind the current progress bar to listen for updates
                         progressListener = new ProgressListener(item, itemViewHolder.binding.uploadProgressBar);
-                        binder.addDatatransferProgressListener(progressListener, item);
+                        uploadHelper.addDatatransferProgressListener(progressListener, item);
                     } else {
                         // not really uploading; stop listening progress if view is reused!
                         if (progressListener != null &&
                             progressListener.isWrapping(itemViewHolder.binding.uploadProgressBar)) {
-                            binder.removeDatatransferProgressListener(progressListener,
-                                                                      progressListener.getUpload() // the one that was added
-                                                                     );
+                            uploadHelper.removeDatatransferProgressListener(progressListener, progressListener.getUpload());
                             progressListener = null;
                         }
                     }
@@ -312,9 +308,9 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
             itemViewHolder.binding.uploadRightButton.setImageResource(R.drawable.ic_action_cancel_grey);
             itemViewHolder.binding.uploadRightButton.setVisibility(View.VISIBLE);
             itemViewHolder.binding.uploadRightButton.setOnClickListener(v -> {
-                FileUploader.FileUploaderBinder uploaderBinder = parentActivity.getFileUploaderBinder();
-                if (uploaderBinder != null) {
-                    uploaderBinder.cancel(item);
+                FilesUploadHelper uploadHelper = parentActivity.getFileUploaderHelper();
+                if (uploadHelper != null) {
+                    uploadHelper.cancel(item);
                     loadUploadItemsFromDb();
                 }
             });
@@ -614,8 +610,8 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
 
             case UPLOAD_IN_PROGRESS:
                 status = parentActivity.getString(R.string.uploads_view_later_waiting_to_upload);
-                FileUploader.FileUploaderBinder binder = parentActivity.getFileUploaderBinder();
-                if (binder != null && binder.isUploadingNow(upload)) {
+                FilesUploadHelper uploadHelper = parentActivity.getFileUploaderHelper();
+                if (uploadHelper != null && uploadHelper.isUploadingNow(upload)) {
                     // really uploading, bind the progress bar to listen for progress updates
                     status = parentActivity.getString(R.string.uploader_upload_in_progress_ticker);
                 }
@@ -862,10 +858,10 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
         }
 
         void fixAndSortItems(OCUpload... array) {
-            FileUploader.FileUploaderBinder binder = parentActivity.getFileUploaderBinder();
+            FilesUploadHelper uploadHelper = parentActivity.getFileUploaderHelper();
 
             for (OCUpload upload : array) {
-                upload.setDataFixed(binder);
+                upload.setDataFixed(uploadHelper);
             }
             Arrays.sort(array, new OCUploadComparator());
 

+ 95 - 4
app/src/main/java/com/owncloud/android/utils/FilesUploadHelper.kt

@@ -22,13 +22,17 @@
 
 package com.owncloud.android.utils
 
+import android.accounts.Account
 import androidx.work.WorkInfo
 import androidx.work.WorkManager
 import com.google.common.util.concurrent.ListenableFuture
 import com.nextcloud.client.account.User
+import com.nextcloud.client.account.UserAccountManager
 import com.nextcloud.client.jobs.BackgroundJobManager
 import com.nextcloud.client.jobs.BackgroundJobManagerImpl
 import com.nextcloud.client.jobs.FilesUploadWorker
+import com.nextcloud.client.jobs.FilesUploadWorker.Companion.buildRemoteName
+import com.nextcloud.client.jobs.FilesUploadWorker.Companion.currentUploadFileOperation
 import com.owncloud.android.MainApp
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.datamodel.UploadsStorageManager
@@ -36,7 +40,9 @@ import com.owncloud.android.datamodel.UploadsStorageManager.UploadStatus
 import com.owncloud.android.db.OCUpload
 import com.owncloud.android.files.services.NameCollisionPolicy
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener
+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.model.ServerFileInterface
 import java.util.concurrent.ExecutionException
 import javax.inject.Inject
 
@@ -44,6 +50,9 @@ class FilesUploadHelper {
     @Inject
     lateinit var backgroundJobManager: BackgroundJobManager
 
+    @Inject
+    lateinit var accountManager: UserAccountManager
+
     @Inject
     lateinit var uploadsStorageManager: UploadsStorageManager
 
@@ -66,7 +75,7 @@ class FilesUploadHelper {
             if (accountName == null || remotePath == null) return
 
             val key: String =
-                FilesUploadWorker.buildRemoteName(accountName, remotePath)
+                buildRemoteName(accountName, remotePath)
             val boundListener = mBoundListeners[key]
 
             boundListener?.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName)
@@ -112,7 +121,7 @@ class FilesUploadHelper {
                 this.nameCollisionPolicy = nameCollisionPolicy
                 isUseWifiOnly = requiresWifi
                 isWhileChargingOnly = requiresCharging
-                uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS
+                uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS
                 this.createdBy = createdBy
                 isCreateRemoteFolder = createRemoteFolder
                 localAction = localBehavior
@@ -144,6 +153,17 @@ class FilesUploadHelper {
         return upload.uploadStatus == UploadStatus.UPLOAD_IN_PROGRESS
     }
 
+    fun isUploadingNow(upload: OCUpload?): Boolean {
+        val currentUploadFileOperation = currentUploadFileOperation
+        if (currentUploadFileOperation == null || currentUploadFileOperation.user == null) return false
+        if (upload == null || upload.accountName != currentUploadFileOperation.user.accountName) return false
+        return if (currentUploadFileOperation.oldFile != null) {
+            // For file conflicts check old file remote path
+            upload.remotePath == currentUploadFileOperation.remotePath || upload.remotePath == currentUploadFileOperation.oldFile!!
+                .remotePath
+        } else upload.remotePath == currentUploadFileOperation.remotePath
+    }
+
     fun uploadUpdatedFile(
         user: User,
         existingFiles: Array<OCFile?>?,
@@ -165,7 +185,7 @@ class FilesUploadHelper {
                     this.localAction = behaviour
                     isUseWifiOnly = false
                     isWhileChargingOnly = false
-                    uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS
+                    uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS
                 }
             }
         }
@@ -176,12 +196,60 @@ class FilesUploadHelper {
     fun retryUpload(upload: OCUpload, user: User) {
         Log_OC.d(this, "retry upload")
 
-        upload.uploadStatus = UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS
+        upload.uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS
         uploadsStorageManager.updateUpload(upload)
 
         backgroundJobManager.startFilesUploadJob(user)
     }
 
+    fun cancel(storedUpload: OCUpload) {
+        cancel(storedUpload.accountName, storedUpload.remotePath, null)
+    }
+
+    fun cancel(account: Account, file: ServerFileInterface) {
+        cancel(account.name, file.remotePath, null)
+    }
+
+    fun cancel(accountName: String?) {
+        // cancelPendingUploads(accountName)
+        FilesUploadHelper().restartUploadJob(accountManager.getUser(accountName).get())
+    }
+
+    fun cancel(user: User) {
+        cancel(user.accountName)
+    }
+
+    fun cancel(accountName: String?, remotePath: String?, resultCode: ResultCode?) {
+        try {
+            cancelFileUpload(remotePath!!, accountManager.getUser(accountName).get())
+        } catch (e: NoSuchElementException) {
+            Log_OC.e(TAG, "Error cancelling current upload because user does not exist!")
+        }
+    }
+
+    fun addDatatransferProgressListener(
+        listener: OnDatatransferProgressListener?,
+        ocUpload: OCUpload?
+    ) {
+        if (ocUpload == null || listener == null) {
+            return
+        }
+        val targetKey = buildRemoteName(ocUpload.accountName, ocUpload.remotePath)
+        addDatatransferProgressListener(listener, targetKey)
+    }
+
+    fun addDatatransferProgressListener(
+        listener: OnDatatransferProgressListener?,
+        user: User?,
+        file: ServerFileInterface?
+    ) {
+        if (user == null || file == null || listener == null) {
+            return
+        }
+        val targetKey = buildRemoteName(user.accountName, file.remotePath)
+        addDatatransferProgressListener(listener, targetKey)
+    }
+
     fun addDatatransferProgressListener(
         listener: OnDatatransferProgressListener,
         targetKey: String
@@ -189,6 +257,29 @@ class FilesUploadHelper {
         mBoundListeners[targetKey] = listener
     }
 
+    fun removeDatatransferProgressListener(
+        listener: OnDatatransferProgressListener?,
+        user: User?,
+        file: ServerFileInterface?
+    ) {
+        if (user == null || file == null || listener == null) {
+            return
+        }
+        val targetKey = buildRemoteName(user.accountName, file.remotePath)
+        removeDatatransferProgressListener(listener, targetKey)
+    }
+
+    fun removeDatatransferProgressListener(
+        listener: OnDatatransferProgressListener?,
+        ocUpload: OCUpload?
+    ) {
+        if (ocUpload == null || listener == null) {
+            return
+        }
+        val targetKey = buildRemoteName(ocUpload.accountName, ocUpload.remotePath)
+        removeDatatransferProgressListener(listener, targetKey)
+    }
+
     fun removeDatatransferProgressListener(
         listener: OnDatatransferProgressListener,
         targetKey: String