diff --git a/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt b/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt index 277f5cef52..629f29df79 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt @@ -182,7 +182,7 @@ class FilesSyncWork( } else { // Check every file in synced folder for changes and update // filesystemDataProvider database (potentially needs a long time) - FilesSyncHelper.insertAllDBEntries(syncedFolder, powerManagementService) + FilesSyncHelper.insertAllDBEntriesForSyncedFolder(syncedFolder) } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt index 283cc0fbab..aaae97adb0 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt @@ -12,9 +12,11 @@ import android.content.Context import android.content.Intent import com.nextcloud.client.account.User import com.nextcloud.client.account.UserAccountManager +import com.nextcloud.client.device.BatteryStatus import com.nextcloud.client.device.PowerManagementService import com.nextcloud.client.jobs.BackgroundJobManager import com.nextcloud.client.jobs.upload.FileUploadWorker.Companion.currentUploadFileOperation +import com.nextcloud.client.network.Connectivity import com.nextcloud.client.network.ConnectivityService import com.owncloud.android.MainApp import com.owncloud.android.datamodel.OCFile @@ -28,9 +30,9 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation import com.owncloud.android.lib.resources.files.model.RemoteFile +import com.owncloud.android.operations.UploadFileOperation import com.owncloud.android.utils.FileUtil import java.io.File -import java.util.Optional import javax.inject.Inject @Suppress("TooManyFunctions") @@ -117,33 +119,41 @@ class FileUploadHelper { failedUploads: Array ): Boolean { var showNotExistMessage = false - val (gotNetwork, _, gotWifi) = connectivityService.connectivity - val batteryStatus = powerManagementService.battery - val charging = batteryStatus.isCharging || batteryStatus.isFull - val isPowerSaving = powerManagementService.isPowerSavingEnabled - var uploadUser = Optional.empty() + val hasGeneralConnection = checkConnectivity(connectivityService) + val connectivity = connectivityService.connectivity + val battery = powerManagementService.battery + val accountNames = accountManager.accounts.filter { + accountManager.getUser(it.name).isPresent + }.map { it.name }.toHashSet() for (failedUpload in failedUploads) { - val isDeleted = !File(failedUpload.localPath).exists() - if (isDeleted) { - showNotExistMessage = true - // 2A. for deleted files, mark as permanently failed - if (failedUpload.lastResult != UploadResult.FILE_NOT_FOUND) { - failedUpload.lastResult = UploadResult.FILE_NOT_FOUND + if (!accountNames.contains(failedUpload.accountName)) { + uploadsStorageManager.removeUpload(failedUpload) + continue + } + + val conditions = + checkUploadConditions(failedUpload, connectivity, battery, powerManagementService, hasGeneralConnection) + + if (conditions != UploadResult.UPLOADED) { + if (failedUpload.lastResult != conditions){ + failedUpload.lastResult = conditions uploadsStorageManager.updateUpload(failedUpload) } - } else if (!isPowerSaving && gotNetwork && - canUploadBeRetried(failedUpload, gotWifi, charging) && !connectivityService.isInternetWalled - ) { - // 2B. for existing local files, try restarting it if possible - failedUpload.uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS - uploadsStorageManager.updateUpload(failedUpload) + if (conditions == UploadResult.FILE_NOT_FOUND) { + showNotExistMessage = true + } + continue } + + failedUpload.uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS + uploadsStorageManager.updateUpload(failedUpload) + } - accountManager.accounts.forEach { - val user = accountManager.getUser(it.name) + accountNames.forEach { + val user = accountManager.getUser(it) if (user.isPresent) backgroundJobManager.startFilesUploadJob(user.get()) } @@ -216,11 +226,52 @@ class FileUploadHelper { return upload.uploadStatus == UploadStatus.UPLOAD_IN_PROGRESS } - private fun canUploadBeRetried(upload: OCUpload, gotWifi: Boolean, isCharging: Boolean): Boolean { - val file = File(upload.localPath) - val needsWifi = upload.isUseWifiOnly - val needsCharging = upload.isWhileChargingOnly - return file.exists() && (!needsWifi || gotWifi) && (!needsCharging || isCharging) + private fun checkConnectivity(connectivityService: ConnectivityService): Boolean { + // check that internet is not behind walled garden + return connectivityService.getConnectivity().isConnected && !connectivityService.isInternetWalled() + + } + + /** + * Dupe of [UploadFileOperation.checkConditions], needed to check if the upload should even be scheduled + * @return [UploadResult.UPLOADED] if the upload should be scheduled, otherwise the reason why it shouldn't + */ + private fun checkUploadConditions( + upload: OCUpload, + connectivity: Connectivity, + battery: BatteryStatus, + powerManagementService: PowerManagementService, + hasGeneralConnection: Boolean + ): UploadResult { + + var conditions = UploadResult.UPLOADED + + // check that internet is available + if (!hasGeneralConnection) { + conditions = UploadResult.NETWORK_CONNECTION + } + + // check that local file exists and skip the upload otherwise + if (!File(upload.localPath).exists()){ + conditions = UploadResult.FILE_NOT_FOUND + } + + // check that connectivity conditions are met and skip the upload otherwise + if (upload.isUseWifiOnly && (!connectivity.isWifi || connectivity.isMetered)) { + conditions = UploadResult.DELAYED_FOR_WIFI + } + + // check if charging conditions are met and delays the upload otherwise + if (upload.isWhileChargingOnly && (!battery.isCharging || !battery.isFull)){ + conditions = UploadResult.DELAYED_FOR_CHARGING + } + + // check that device is not in power save mode + if (powerManagementService.isPowerSavingEnabled) { + conditions = UploadResult.DELAYED_IN_POWER_SAVE_MODE + } + + return conditions } @Suppress("ReturnCount") diff --git a/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java b/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java index 1987abfc3c..1be5ebc802 100644 --- a/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java +++ b/app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.java @@ -108,7 +108,7 @@ public final class FilesSyncHelper { } } - private static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) { + public static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) { final Context context = MainApp.getAppContext(); final ContentResolver contentResolver = context.getContentResolver(); @@ -146,18 +146,6 @@ public final class FilesSyncHelper { } } - public static void insertAllDBEntries(SyncedFolder syncedFolder, - PowerManagementService powerManagementService) { - if (syncedFolder.isEnabled() && - !(syncedFolder.isChargingOnly() && - !powerManagementService.getBattery().isCharging() && - !powerManagementService.getBattery().isFull() - ) - ) { - insertAllDBEntriesForSyncedFolder(syncedFolder); - } - } - public static void insertChangedEntries(SyncedFolder syncedFolder, String[] changedFiles) { final ContentResolver contentResolver = MainApp.getAppContext().getContentResolver(); @@ -248,66 +236,13 @@ public final class FilesSyncHelper { final UserAccountManager accountManager, final ConnectivityService connectivityService, final PowerManagementService powerManagementService) { - boolean accountExists; - - boolean whileChargingOnly = true; - boolean useWifiOnly = true; - - // Make all in progress downloads failed to restart upload worker - uploadsStorageManager.failInProgressUploads(UploadResult.SERVICE_INTERRUPTED); - - OCUpload[] failedUploads = uploadsStorageManager.getFailedUploads(); - - for (OCUpload failedUpload : failedUploads) { - accountExists = false; - if (!failedUpload.isWhileChargingOnly()) { - whileChargingOnly = false; - } - if (!failedUpload.isUseWifiOnly()) { - useWifiOnly = false; - } - - // check if accounts still exists - for (Account account : accountManager.getAccounts()) { - if (account.name.equals(failedUpload.getAccountName())) { - accountExists = true; - break; - } - } - - if (!accountExists) { - uploadsStorageManager.removeUpload(failedUpload); - } - } - - failedUploads = uploadsStorageManager.getFailedUploads(); - if (failedUploads.length == 0) { - //nothing to do - return; - } - - if (whileChargingOnly) { - final BatteryStatus batteryStatus = powerManagementService.getBattery(); - final boolean charging = batteryStatus.isCharging() || batteryStatus.isFull(); - if (!charging) { - //all uploads requires charging - return; - } - } - - if (useWifiOnly && !connectivityService.getConnectivity().isWifi()) { - //all uploads requires wifi - return; - } - + new Thread(() -> { - if (connectivityService.getConnectivity().isConnected()) { - FileUploadHelper.Companion.instance().retryFailedUploads( - uploadsStorageManager, - connectivityService, - accountManager, - powerManagementService); - } + FileUploadHelper.Companion.instance().retryFailedUploads( + uploadsStorageManager, + connectivityService, + accountManager, + powerManagementService); }).start(); }