Rebase master

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2024-01-12 14:11:55 +01:00 committed by Jonas Mayer
parent 584bac9ae7
commit 3cbd8ba8e6
8 changed files with 113 additions and 103 deletions

View file

@ -31,12 +31,12 @@ import android.view.Menu;
import com.nextcloud.android.files.FileLockingHelper;
import com.nextcloud.client.account.User;
import com.nextcloud.client.editimage.EditImageActivity;
import com.nextcloud.client.files.downloader.FileDownloadHelper;
import com.nextcloud.client.jobs.download.FileDownloadHelper;
import com.nextcloud.client.jobs.upload.FileUploadHelper;
import com.nextcloud.utils.EditorUtils;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.lib.resources.status.OCCapability;
import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
import com.owncloud.android.ui.activity.ComponentsGetter;
@ -383,10 +383,9 @@ public class FileMenuFilter {
boolean synchronizing = false;
if (componentsGetter != null && !files.isEmpty() && user != null) {
OperationsServiceBinder opsBinder = componentsGetter.getOperationsServiceBinder();
FileUploaderBinder uploaderBinder = componentsGetter.getFileUploaderBinder();
synchronizing = anyFileSynchronizing(opsBinder) || // comparing local and remote
anyFileDownloading() ||
anyFileUploading(uploaderBinder);
anyFileDownloading() ||
anyFileUploading();
}
return synchronizing;
}
@ -411,21 +410,20 @@ public class FileMenuFilter {
return false;
}
private boolean anyFileUploading(FileUploaderBinder uploaderBinder) {
boolean uploading = false;
if (uploaderBinder != null) {
for (Iterator<OCFile> iterator = files.iterator(); !uploading && iterator.hasNext(); ) {
uploading = uploaderBinder.isUploading(user, iterator.next());
private boolean anyFileUploading() {
for (OCFile file : files) {
if (FileUploadHelper.Companion.instance().isUploading(user, file)) {
return true;
}
}
return uploading;
return false;
}
private boolean isShareApiEnabled(OCCapability capability) {
return capability != null &&
(capability.getFilesSharingApiEnabled().isTrue() ||
capability.getFilesSharingApiEnabled().isUnknown()
);
(capability.getFilesSharingApiEnabled().isTrue() ||
capability.getFilesSharingApiEnabled().isUnknown()
);
}
private boolean isShareWithUsersAllowed() {

View file

@ -750,7 +750,7 @@ public class FileUploader extends Service
}
public void clearListeners() {
FilesUploadHelper.Progress.getMBoundListeners().clear();
FilesUploadHelper.Companion.getMBoundListeners().clear();
mBoundListeners.clear();
}

View file

@ -25,13 +25,10 @@ package com.owncloud.android.ui.activity;
import android.accounts.Account;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -181,6 +178,7 @@ public class UploadListActivity extends FileActivity {
swipeListRefreshLayout.setOnRefreshListener(this::refresh);
loadItems();
uploadListAdapter.loadUploadItemsFromDb();
}
private void loadItems() {
@ -320,44 +318,6 @@ public class UploadListActivity extends FileActivity {
}
}
@Override
protected ServiceConnection newTransferenceServiceConnection() {
return new UploadListServiceConnection();
}
/**
* Defines callbacks for service binding, passed to bindService()
*/
private class UploadListServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
if (service instanceof FileUploaderBinder) {
if (mUploaderBinder == null) {
mUploaderBinder = (FileUploaderBinder) service;
Log_OC.d(TAG, "UploadListActivity connected to Upload service. component: " +
component + " service: " + service);
uploadListAdapter.loadUploadItemsFromDb();
} else {
Log_OC.d(TAG, "mUploaderBinder already set. mUploaderBinder: " +
mUploaderBinder + " service:" + service);
}
} else {
Log_OC.d(TAG, "UploadListActivity not connected to Upload service. component: " +
component + " service: " + service);
}
}
@Override
public void onServiceDisconnected(ComponentName component) {
if (component.equals(new ComponentName(UploadListActivity.this, FileUploader.class))) {
Log_OC.d(TAG, "UploadListActivity suddenly disconnected from Upload service");
mUploaderBinder = null;
}
}
}
/**
* Once the file upload has changed its status -> update uploads list view
*/

View file

@ -32,7 +32,8 @@ import androidx.core.content.res.ResourcesCompat
import com.elyeproj.loaderviewlibrary.LoaderImageView
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.client.account.User
import com.nextcloud.client.files.downloader.FileDownloadHelper
import com.nextcloud.client.jobs.download.FileDownloadHelper
import com.nextcloud.client.jobs.upload.FileUploadHelper
import com.nextcloud.client.preferences.AppPreferences
import com.nextcloud.utils.extensions.createRoundedOutline
import com.owncloud.android.R
@ -53,6 +54,7 @@ import com.owncloud.android.utils.theme.ViewThemeUtils
@Suppress("LongParameterList", "TooManyFunctions")
class OCFileListDelegate(
private val fileUploadHelper: FileUploadHelper,
private val context: Context,
private val ocFileListFragmentInterface: OCFileListFragmentInterface,
private val user: User,
@ -343,12 +345,11 @@ class OCFileListDelegate(
private fun showLocalFileIndicator(file: OCFile, gridViewHolder: ListGridImageViewHolder) {
val operationsServiceBinder = transferServiceGetter.operationsServiceBinder
val fileUploaderBinder = transferServiceGetter.fileUploaderBinder
val icon: Int? = when {
operationsServiceBinder?.isSynchronizing(user, file) == true ||
FileDownloadHelper.instance().isDownloading(user, file) ||
fileUploaderBinder?.isUploading(user, file) == true -> {
fileUploadHelper.isUploading(user, file) -> {
// synchronizing, downloading or uploading
R.drawable.ic_synchronizing
}

View file

@ -44,8 +44,9 @@ import com.google.android.material.tabs.TabLayout;
import com.nextcloud.client.account.User;
import com.nextcloud.client.account.UserAccountManager;
import com.nextcloud.client.di.Injectable;
import com.nextcloud.client.files.downloader.FileDownloadHelper;
import com.nextcloud.client.jobs.BackgroundJobManager;
import com.nextcloud.client.jobs.download.FileDownloadHelper;
import com.nextcloud.client.jobs.upload.FileUploadHelper;
import com.nextcloud.client.network.ClientFactory;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.client.preferences.AppPreferences;
@ -58,7 +59,6 @@ import com.owncloud.android.databinding.FileDetailsFragmentBinding;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@ -233,7 +233,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
} else {
binding.emptyList.emptyListView.setVisibility(View.GONE);
}
Context context = getContext();
if (context == null) {
return null;
@ -506,7 +506,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
*
* @param transferring Flag signaling if the file should be considered as downloading or uploading, although
* {@link FileDownloadHelper#isDownloading(User, OCFile)} and
* {@link FileUploaderBinder#isUploading(User, OCFile)} return false.
* {@link FileUploadHelper#isUploading(User, OCFile)} return false.
* @param refresh If 'true', try to refresh the whole file from the database
*/
public void updateFileDetails(boolean transferring, boolean refresh) {
@ -537,10 +537,9 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
setFavoriteIconStatus(file.isFavorite());
// configure UI for depending upon local state of the file
FileUploaderBinder uploaderBinder = containerActivity.getFileUploaderBinder();
if (transferring
|| (FileDownloadHelper.Companion.instance().isDownloading(user, file))
|| (uploaderBinder != null && uploaderBinder.isUploading(user, file))) {
|| (FileUploadHelper.Companion.instance().isUploading(user, file))) {
setButtonsForTransferring();
} else if (file.isDown()) {
@ -661,11 +660,10 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
// show the progress bar for the transfer
binding.progressBlock.setVisibility(View.VISIBLE);
binding.progressText.setVisibility(View.VISIBLE);
FileUploaderBinder uploaderBinder = containerActivity.getFileUploaderBinder();
if (FileDownloadHelper.Companion.instance().isDownloading(user, getFile())) {
binding.progressText.setText(R.string.downloader_download_in_progress_ticker);
} else {
if (uploaderBinder != null && uploaderBinder.isUploading(user, getFile())) {
if (FileUploadHelper.Companion.instance().isUploading(user, getFile())) {
binding.progressText.setText(R.string.uploader_upload_in_progress_ticker);
}
}
@ -698,9 +696,15 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
containerActivity.getFileDownloadProgressListener().
addDataTransferProgressListener(progressListener, getFile());
}
if (containerActivity.getFileUploaderBinder() != null) {
containerActivity.getFileUploaderBinder().
addDatatransferProgressListener(progressListener, user, getFile());
if (containerActivity.getFileUploaderHelper() != null) {
OCFile file = getFile();
if (user == null || file == null) {
return;
}
String targetKey = FileUploadHelper.Companion.buildRemoteName(user.getAccountName(), file.getRemotePath());
containerActivity.getFileUploaderHelper().addUploadTransferProgressListener(progressListener, targetKey);
}
} else {
Log_OC.d(TAG, "progressListener == null");
@ -713,9 +717,15 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
containerActivity.getFileDownloadProgressListener().
removeDataTransferProgressListener(progressListener, getFile());
}
if (containerActivity.getFileUploaderBinder() != null) {
containerActivity.getFileUploaderBinder().
removeDatatransferProgressListener(progressListener, user, getFile());
if (containerActivity.getFileUploaderHelper() != null) {
OCFile file = getFile();
if (user == null || file == null) {
return;
}
String targetKey = FileUploadHelper.Companion.buildRemoteName(user.getAccountName(), file.getRemotePath());
containerActivity.getFileUploaderHelper().removeUploadTransferProgressListener(progressListener, targetKey);
}
}
}

View file

@ -26,7 +26,6 @@ import android.os.Bundle;
import com.nextcloud.utils.extensions.BundleExtensionsKt;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.ui.activity.ComponentsGetter;
import androidx.annotation.Nullable;
@ -106,7 +105,7 @@ public class FileFragment extends Fragment {
} catch (ClassCastException e) {
throw new IllegalArgumentException(activity.toString() + " must implement " +
ContainerActivity.class.getSimpleName(), e);
ContainerActivity.class.getSimpleName(), e);
}
}
@ -159,8 +158,8 @@ public class FileFragment extends Fragment {
* This happens when a download or upload is started or ended for a file.
*
* This method is necessary by now to update the user interface of the double-pane layout
* in tablets because methods {@link //FileDownloaderBinder # isDownloading(Account, OCFile)}
* and {@link FileUploaderBinder# isUploading(Account, OCFile)}
* in tablets because methods FileDownloaderBinder.isDownloading(Account, OCFile)
* and FilesUploadHelper.isUploading(Account, OCFile)
* won't provide the needed response before the method where this is called finishes.
*
* TODO Remove this when the transfer state of a file is kept in the database

View file

@ -47,8 +47,9 @@ import android.webkit.MimeTypeMap;
import com.nextcloud.client.account.CurrentAccountProvider;
import com.nextcloud.client.account.User;
import com.nextcloud.client.files.downloader.FileDownloadHelper;
import com.nextcloud.client.jobs.BackgroundJobManager;
import com.nextcloud.client.jobs.download.FileDownloadHelper;
import com.nextcloud.client.jobs.upload.FileUploadHelper;
import com.nextcloud.client.network.ConnectivityService;
import com.nextcloud.java.util.Optional;
import com.nextcloud.utils.EditorUtils;
@ -59,7 +60,6 @@ import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.StreamMediaFileOperation;
import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
import com.owncloud.android.lib.common.utils.Log_OC;
import com.owncloud.android.lib.resources.files.CheckEtagRemoteOperation;
@ -104,6 +104,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -1010,9 +1011,12 @@ public class FileOperationsHelper {
FileDownloadHelper.Companion.instance().cancelPendingOrCurrentDownloads(currentUser, files);
}
FileUploaderBinder uploaderBinder = fileActivity.getFileUploaderBinder();
if (uploaderBinder != null && uploaderBinder.isUploading(currentUser, file)) {
uploaderBinder.cancel(currentUser.toPlatformAccount(), file);
if (FileUploadHelper.Companion.instance().isUploading(currentUser, file)) {
try {
FileUploadHelper.Companion.instance().cancelFileUpload(file.getRemotePath(), currentUser.getAccountName());
} catch (NoSuchElementException e) {
Log_OC.e(TAG, "Error cancelling current upload because user does not exist!");
}
}
}

View file

@ -22,16 +22,22 @@
package com.owncloud.android.utils
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.jobs.BackgroundJobManager
import com.nextcloud.client.jobs.BackgroundJobManagerImpl
import com.nextcloud.client.jobs.FilesUploadWorker
import com.owncloud.android.MainApp
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.files.services.NameCollisionPolicy
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener
import com.owncloud.android.lib.common.utils.Log_OC
import java.util.concurrent.ExecutionException
import javax.inject.Inject
class FilesUploadHelper {
@ -45,6 +51,50 @@ class FilesUploadHelper {
MainApp.getAppComponent().inject(this)
}
companion object {
private val TAG = FilesUploadWorker::class.java.simpleName
val mBoundListeners = HashMap<String, OnDatatransferProgressListener>()
fun onTransferProgress(
accountName: String?,
remotePath: String?,
progressRate: Long,
totalTransferredSoFar: Long,
totalToTransfer: Long,
fileName: String?
) {
if (accountName == null || remotePath == null) return
val key: String =
FilesUploadWorker.buildRemoteName(accountName, remotePath)
val boundListener = mBoundListeners[key]
boundListener?.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName)
}
fun isWorkScheduled(tag: String): Boolean {
val instance = WorkManager.getInstance(MainApp.getAppContext())
val statuses: ListenableFuture<List<WorkInfo>> = instance.getWorkInfosByTag(tag)
var running = false
var workInfoList: List<WorkInfo> = emptyList()
try {
workInfoList = statuses.get()
} catch (e: ExecutionException) {
Log_OC.d(TAG, "ExecutionException in isWorkScheduled: $e")
} catch (e: InterruptedException) {
Log_OC.d(TAG, "InterruptedException in isWorkScheduled: $e")
}
for (workInfo in workInfoList) {
val state = workInfo.state
running = running || (state == WorkInfo.State.RUNNING || state == WorkInfo.State.ENQUEUED)
}
return running
}
}
@Suppress("LongParameterList")
fun uploadNewFiles(
user: User,
@ -85,6 +135,15 @@ class FilesUploadHelper {
backgroundJobManager.startFilesUploadJob(user)
}
fun isUploading(user: User?, file: OCFile?): Boolean {
if (user == null || file == null || !isWorkScheduled(BackgroundJobManagerImpl.JOB_FILES_UPLOAD)) {
return false
}
val upload: OCUpload = uploadsStorageManager.getUploadByRemotePath(file.remotePath) ?: return false
return upload.uploadStatus == UploadStatus.UPLOAD_IN_PROGRESS
}
fun uploadUpdatedFile(
user: User,
existingFiles: Array<OCFile?>?,
@ -138,25 +197,4 @@ class FilesUploadHelper {
mBoundListeners.remove(targetKey)
}
}
companion object Progress {
val mBoundListeners = HashMap<String, OnDatatransferProgressListener>()
fun onTransferProgress(
accountName: String?,
remotePath: String?,
progressRate: Long,
totalTransferredSoFar: Long,
totalToTransfer: Long,
fileName: String?
) {
if (accountName == null || remotePath == null) return
val key: String =
FilesUploadWorker.buildRemoteName(accountName, remotePath)
val boundListener = mBoundListeners[key]
boundListener?.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName)
}
}
}