diff --git a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt index 9b8d6edcb7..0a79446f34 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt @@ -24,7 +24,9 @@ import com.nextcloud.model.WorkerStateLiveData import com.owncloud.android.datamodel.FileDataStorageManager import com.owncloud.android.datamodel.ThumbnailsCacheManager 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.OwnCloudClientManagerFactory import com.owncloud.android.lib.common.network.OnDatatransferProgressListener @@ -32,6 +34,7 @@ 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.operations.UploadFileOperation +import com.owncloud.android.operations.UploadFileOperation.uploadedSourcePath import com.owncloud.android.utils.ErrorMessageAdapter import com.owncloud.android.utils.theme.ViewThemeUtils import java.io.File @@ -235,11 +238,30 @@ class FileUploadWorker( } private fun cleanupUploadProcess(result: RemoteOperationResult, operation: UploadFileOperation) { - if (!(isStopped && result.isCancelled)) { - uploadsStorageManager.updateDatabaseUploadResult(result, operation) - notifyUploadResult(operation, result) - notificationManager.dismissWorkerNotifications() + if (operation.originalStoragePath == uploadedSourcePath) { + // TODO + // This is not ideal fix. When uploading file to the encrypted folder server returns 404 FILE_NOT_FOUND + // However file upload successfully completed. This fix mimic success, if upload successfully completed with + // receiving path + val localPath: String? = + if (LOCAL_BEHAVIOUR_MOVE == operation.localBehaviour) operation.storagePath else null + + uploadsStorageManager.updateUploadStatus( + operation.ocUploadId, + UploadStatus.UPLOAD_SUCCEEDED, + UploadResult.UPLOADED, + operation.remotePath, + localPath + ) + notificationManager.dismissOldErrorNotification(operation) + } else { + if (!(isStopped && result.isCancelled)) { + uploadsStorageManager.updateDatabaseUploadResult(result, operation) + notifyUploadResult(operation, result) + } } + + notificationManager.dismissWorkerNotifications() } @Suppress("ReturnCount") @@ -288,17 +310,18 @@ class FileUploadWorker( context.resources ) - // FIXME SYNC_CONFLICT passes wrong OCFile, check ConflictsResolveActivity.createIntent usage val conflictResolveIntent = if (uploadResult.code == ResultCode.SYNC_CONFLICT) { intents.conflictResolveActionIntents(context, uploadFileOperation) } else { null } + val credentialIntent: PendingIntent? = if (uploadResult.code == ResultCode.UNAUTHORIZED) { intents.credentialIntent(uploadFileOperation) } else { null } + notifyForFailedResult(uploadResult.code, conflictResolveIntent, credentialIntent, errorMessage) showNewNotification(uploadFileOperation) } diff --git a/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java index e5feb111e9..e0cd402ab9 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java @@ -256,7 +256,7 @@ public class UploadsStorageManager extends Observable { * @param localPath path of the file to upload in the device storage * @return 1 if file status was updated, else 0. */ - private int updateUploadStatus(long id, UploadStatus status, UploadResult result, String remotePath, + public int updateUploadStatus(long id, UploadStatus status, UploadResult result, String remotePath, String localPath) { //Log_OC.v(TAG, "Updating "+filepath+" with uploadStatus="+status +" and result="+result); diff --git a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java index 0181b4f4f5..b54a982454 100644 --- a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -23,6 +23,7 @@ package com.owncloud.android.operations; import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; import android.net.Uri; import android.text.TextUtils; @@ -98,6 +99,9 @@ import javax.crypto.Cipher; import androidx.annotation.CheckResult; import androidx.annotation.Nullable; +import androidx.localbroadcastmanager.content.LocalBroadcastManager; + +import static com.owncloud.android.ui.activity.FileDisplayActivity.REFRESH_FOLDER_EVENT_RECEIVER; /** @@ -466,6 +470,7 @@ public class UploadFileOperation extends SyncOperation { if (result != null) { return result; } + /***** E2E *****/ // Only on V2+: whenever we change something, increase counter long counter = -1; @@ -485,12 +490,6 @@ public class UploadFileOperation extends SyncOperation { // Update metadata EncryptionUtilsV2 encryptionUtilsV2 = new EncryptionUtilsV2(); -// kotlin.Pair metadataPair = -// encryptionUtilsV2.retrieveMetadata(parentFile, -// client, -// user, -// mContext); - Object object = EncryptionUtils.downloadFolderMetadata(parentFile, client, mContext, user); if (object instanceof DecryptedFolderMetadataFileV1 decrypted && decrypted.getMetadata() != null) { metadataExists = true; @@ -706,10 +705,6 @@ public class UploadFileOperation extends SyncOperation { // unlock result = EncryptionUtils.unlockFolderV1(parentFile, client, token); - - if (result.isSuccess()) { - token = null; - } } else { DecryptedFolderMetadataFile metadata = (DecryptedFolderMetadataFile) object; encryptionUtilsV2.addFileToMetadata( @@ -733,10 +728,6 @@ public class UploadFileOperation extends SyncOperation { // unlock result = EncryptionUtils.unlockFolder(parentFile, client, token); - - if (result.isSuccess()) { - token = null; - } } encryptedTempFile.delete(); @@ -751,6 +742,7 @@ public class UploadFileOperation extends SyncOperation { result = new RemoteOperationResult(e); } finally { mUploadStarted.set(false); + sendRefreshFolderEventBroadcast(); if (fileLock != null) { try { @@ -768,6 +760,17 @@ public class UploadFileOperation extends SyncOperation { } logResult(result, mFile.getStoragePath(), mFile.getRemotePath()); + + // unlock must be done always + if (token != null) { + RemoteOperationResult unlockFolderResult = EncryptionUtils.unlockFolder(parentFile, + client, + token); + + if (!unlockFolderResult.isSuccess()) { + result = unlockFolderResult; + } + } } if (result.isSuccess()) { @@ -776,17 +779,6 @@ public class UploadFileOperation extends SyncOperation { getStorageManager().saveConflict(mFile, mFile.getEtagInConflict()); } - // unlock must be done always - if (token != null) { - RemoteOperationResult unlockFolderResult = EncryptionUtils.unlockFolder(parentFile, - client, - token); - - if (!unlockFolderResult.isSuccess()) { - return unlockFolderResult; - } - } - // delete temporal file if (temporalFile != null && temporalFile.exists() && !temporalFile.delete()) { Log_OC.e(TAG, "Could not delete temporal file " + temporalFile.getAbsolutePath()); @@ -795,6 +787,11 @@ public class UploadFileOperation extends SyncOperation { return result; } + private void sendRefreshFolderEventBroadcast() { + Intent intent = new Intent(REFRESH_FOLDER_EVENT_RECEIVER); + LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent); + } + private RemoteOperationResult checkConditions(File originalFile) { RemoteOperationResult remoteOperationResult = null; @@ -1001,8 +998,11 @@ public class UploadFileOperation extends SyncOperation { } } + public static String uploadedSourcePath; + private void logResult(RemoteOperationResult result, String sourcePath, String targetPath) { if (result.isSuccess()) { + uploadedSourcePath = sourcePath; Log_OC.i(TAG, "Upload of " + sourcePath + " to " + targetPath + ": " + result.getLogMessage()); } else { if (result.getException() != null) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java index de4d49f366..8290993b68 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java @@ -69,6 +69,7 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper; import com.nextcloud.client.jobs.download.FileDownloadWorker; import com.nextcloud.client.jobs.upload.FileUploadHelper; import com.nextcloud.client.jobs.upload.FileUploadWorker; +import com.nextcloud.client.jobs.upload.UploadNotificationManager; import com.nextcloud.client.media.PlayerServiceConnection; import com.nextcloud.client.network.ClientFactory; import com.nextcloud.client.network.ConnectivityService; @@ -229,6 +230,8 @@ public class FileDisplayActivity extends FileActivity public static final String KEY_IS_SEARCH_OPEN = "IS_SEARCH_OPEN"; public static final String KEY_SEARCH_QUERY = "SEARCH_QUERY"; + public static final String REFRESH_FOLDER_EVENT_RECEIVER = "REFRESH_FOLDER_EVENT"; + private String searchQuery = ""; private boolean searchOpen; @@ -236,6 +239,7 @@ public class FileDisplayActivity extends FileActivity private PlayerServiceConnection mPlayerConnection; private Optional lastDisplayedUser = Optional.empty(); private int menuItemId = -1; + @Inject AppPreferences preferences; @Inject AppInfo appInfo; @@ -283,6 +287,7 @@ public class FileDisplayActivity extends FileActivity initSyncBroadcastReceiver(); observeWorkerState(); + registerRefreshFolderEventReceiver(); } @SuppressWarnings("unchecked") @@ -2296,6 +2301,24 @@ public class FileDisplayActivity extends FileActivity checkForNewDevVersionNecessary(getApplicationContext()); } + private void registerRefreshFolderEventReceiver() { + IntentFilter filter = new IntentFilter(REFRESH_FOLDER_EVENT_RECEIVER); + LocalBroadcastManager.getInstance(this).registerReceiver(refreshFolderEventReceiver, filter); + } + + private final BroadcastReceiver refreshFolderEventReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + syncAndUpdateFolder(true); + } + }; + + @Override + protected void onDestroy() { + LocalBroadcastManager.getInstance(this).unregisterReceiver(refreshFolderEventReceiver); + super.onDestroy(); + } + @Override protected void onRestart() { super.onRestart(); diff --git a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java index 434bc5a83a..414cb83846 100644 --- a/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java @@ -516,8 +516,12 @@ public final class EncryptionUtils { new TypeToken<>() { }); - if ("2.0".equals(v2.getVersion()) || "2".equals(v2.getVersion())) { - return E2EVersion.V2_0; + if (v2 != null) { + if ("2.0".equals(v2.getVersion()) || "2".equals(v2.getVersion())) { + return E2EVersion.V2_0; + } + } else { + return E2EVersion.UNKNOWN; } }