Skip to content

Commit 36233d8

Browse files
committed
fix: choose correct upload ids for retry
Signed-off-by: alperozturk <alper_ozturk@proton.me>
1 parent 90ebd53 commit 36233d8

File tree

3 files changed

+72
-93
lines changed

3 files changed

+72
-93
lines changed

app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -88,32 +88,39 @@ class FileUploadHelper {
8888
fun buildRemoteName(accountName: String, remotePath: String): String = accountName + remotePath
8989
}
9090

91+
fun getUploadsByStatus(accountName: String, status: UploadStatus, onCompleted: (Array<OCUpload>) -> Unit) {
92+
ioScope.launch {
93+
val result = uploadsStorageManager.uploadDao.getUploadsByStatus(
94+
accountName,
95+
status.value
96+
).map { it.toOCUpload(null) }.toTypedArray()
97+
onCompleted(result)
98+
}
99+
}
100+
91101
fun retryFailedUploads(
92102
uploadsStorageManager: UploadsStorageManager,
93103
connectivityService: ConnectivityService,
94104
accountManager: UserAccountManager,
95105
powerManagementService: PowerManagementService
96106
) {
97-
if (retryFailedUploadsSemaphore.tryAcquire()) {
98-
try {
99-
val failedUploads = uploadsStorageManager.failedUploads
100-
if (failedUploads == null || failedUploads.isEmpty()) {
101-
Log_OC.d(TAG, "Failed uploads are empty or null")
102-
return
103-
}
107+
if (!retryFailedUploadsSemaphore.tryAcquire()) {
108+
Log_OC.d(TAG, "skipping retryFailedUploads, already running")
109+
return
110+
}
104111

112+
try {
113+
getUploadsByStatus(accountManager.user.accountName, UploadStatus.UPLOAD_FAILED) {
105114
retryUploads(
106115
uploadsStorageManager,
107116
connectivityService,
108117
accountManager,
109118
powerManagementService,
110-
failedUploads
119+
uploads = it
111120
)
112-
} finally {
113-
retryFailedUploadsSemaphore.release()
114121
}
115-
} else {
116-
Log_OC.d(TAG, "Skip retryFailedUploads since it is already running")
122+
} finally {
123+
retryFailedUploadsSemaphore.release()
117124
}
118125
}
119126

@@ -123,18 +130,18 @@ class FileUploadHelper {
123130
accountManager: UserAccountManager,
124131
powerManagementService: PowerManagementService
125132
): Boolean {
126-
val cancelledUploads = uploadsStorageManager.cancelledUploadsForCurrentAccount
127-
if (cancelledUploads == null || cancelledUploads.isEmpty()) {
128-
return false
133+
var result = false
134+
getUploadsByStatus(accountManager.user.accountName, UploadStatus.UPLOAD_CANCELLED) {
135+
result = retryUploads(
136+
uploadsStorageManager,
137+
connectivityService,
138+
accountManager,
139+
powerManagementService,
140+
it
141+
)
129142
}
130143

131-
return retryUploads(
132-
uploadsStorageManager,
133-
connectivityService,
134-
accountManager,
135-
powerManagementService,
136-
cancelledUploads
137-
)
144+
return result
138145
}
139146

140147
@Suppress("ComplexCondition")
@@ -143,51 +150,51 @@ class FileUploadHelper {
143150
connectivityService: ConnectivityService,
144151
accountManager: UserAccountManager,
145152
powerManagementService: PowerManagementService,
146-
failedUploads: Array<OCUpload>
153+
uploads: Array<OCUpload>
147154
): Boolean {
148155
var showNotExistMessage = false
149156
val isOnline = checkConnectivity(connectivityService)
150157
val connectivity = connectivityService.connectivity
151158
val batteryStatus = powerManagementService.battery
152-
val accountNames = accountManager.accounts.filter { account ->
153-
accountManager.getUser(account.name).isPresent
154-
}.map { account ->
155-
account.name
156-
}.toHashSet()
157-
158-
for (failedUpload in failedUploads) {
159-
if (!accountNames.contains(failedUpload.accountName)) {
160-
uploadsStorageManager.removeUpload(failedUpload)
161-
continue
162-
}
163159

164-
val uploadResult =
165-
checkUploadConditions(failedUpload, connectivity, batteryStatus, powerManagementService, isOnline)
160+
val uploadsToRetry = mutableListOf<Long>()
161+
162+
for (upload in uploads) {
163+
val uploadResult = checkUploadConditions(
164+
upload,
165+
connectivity,
166+
batteryStatus,
167+
powerManagementService,
168+
isOnline
169+
)
166170

167171
if (uploadResult != UploadResult.UPLOADED) {
168-
if (failedUpload.lastResult != uploadResult) {
172+
if (upload.lastResult != uploadResult) {
169173
// Setting Upload status else cancelled uploads will behave wrong, when retrying
170174
// Needs to happen first since lastResult wil be overwritten by setter
171-
failedUpload.uploadStatus = UploadStatus.UPLOAD_FAILED
175+
upload.uploadStatus = UploadStatus.UPLOAD_FAILED
172176

173-
failedUpload.lastResult = uploadResult
174-
uploadsStorageManager.updateUpload(failedUpload)
177+
upload.lastResult = uploadResult
178+
uploadsStorageManager.updateUpload(upload)
175179
}
176180
if (uploadResult == UploadResult.FILE_NOT_FOUND) {
177181
showNotExistMessage = true
178182
}
179183
continue
180184
}
181185

182-
failedUpload.uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS
183-
uploadsStorageManager.updateUpload(failedUpload)
186+
// Only uploads that passed checks get marked in progress and are collected for scheduling
187+
upload.uploadStatus = UploadStatus.UPLOAD_IN_PROGRESS
188+
uploadsStorageManager.updateUpload(upload)
189+
uploadsToRetry.add(upload.uploadId)
184190
}
185191

186-
accountNames.forEach { accountName ->
187-
val user = accountManager.getUser(accountName)
188-
if (user.isPresent) {
189-
backgroundJobManager.startFilesUploadJob(user.get(), failedUploads.getUploadIds(), false)
190-
}
192+
if (uploadsToRetry.isNotEmpty()) {
193+
backgroundJobManager.startFilesUploadJob(
194+
accountManager.user,
195+
uploadsToRetry.toLongArray(),
196+
false
197+
)
191198
}
192199

193200
return showNotExistMessage
@@ -235,15 +242,6 @@ class FileUploadHelper {
235242
}
236243
}
237244

238-
fun getUploadsByStatus(accountName: String, status: UploadStatus, onCompleted: (Array<OCUpload>) -> Unit) {
239-
ioScope.launch {
240-
val result =
241-
uploadsStorageManager.uploadDao.getUploadsByStatus(accountName, status.value)
242-
.map { it.toOCUpload(null) }.toTypedArray()
243-
onCompleted(result)
244-
}
245-
}
246-
247245
fun cancelAndRestartUploadJob(user: User, uploadIds: LongArray) {
248246
backgroundJobManager.run {
249247
cancelFilesUploadJob(user)

app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -483,35 +483,10 @@ public long[] getCurrentUploadIds(final @NonNull String accountName) {
483483
.toArray();
484484
}
485485

486-
/**
487-
* Get all failed uploads.
488-
*/
489-
public OCUpload[] getFailedUploads() {
490-
return getUploads("(" + ProviderTableMeta.UPLOADS_STATUS + IS_EQUAL +
491-
OR + ProviderTableMeta.UPLOADS_LAST_RESULT +
492-
EQUAL + UploadResult.DELAYED_FOR_WIFI.getValue() +
493-
OR + ProviderTableMeta.UPLOADS_LAST_RESULT +
494-
EQUAL + UploadResult.LOCK_FAILED.getValue() +
495-
OR + ProviderTableMeta.UPLOADS_LAST_RESULT +
496-
EQUAL + UploadResult.DELAYED_FOR_CHARGING.getValue() +
497-
OR + ProviderTableMeta.UPLOADS_LAST_RESULT +
498-
EQUAL + UploadResult.DELAYED_IN_POWER_SAVE_MODE.getValue() +
499-
" ) AND " + ProviderTableMeta.UPLOADS_LAST_RESULT +
500-
"!= " + UploadResult.VIRUS_DETECTED.getValue()
501-
, String.valueOf(UploadStatus.UPLOAD_FAILED.value));
502-
}
503-
504486
public OCUpload[] getUploadsForAccount(final @NonNull String accountName) {
505487
return getUploads(ProviderTableMeta.UPLOADS_ACCOUNT_NAME + IS_EQUAL, accountName);
506488
}
507489

508-
public OCUpload[] getCancelledUploadsForCurrentAccount() {
509-
User user = currentAccountProvider.getUser();
510-
511-
return getUploads(ProviderTableMeta.UPLOADS_STATUS + EQUAL + UploadStatus.UPLOAD_CANCELLED.value + AND +
512-
ProviderTableMeta.UPLOADS_ACCOUNT_NAME + IS_EQUAL, user.getAccountName());
513-
}
514-
515490
private ContentResolver getDB() {
516491
return contentResolver;
517492
}

app/src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.owncloud.android.datamodel.OCFile;
3636
import com.owncloud.android.datamodel.SyncedFolderProvider;
3737
import com.owncloud.android.datamodel.UploadsStorageManager;
38+
import com.owncloud.android.db.OCUpload;
3839
import com.owncloud.android.lib.common.operations.RemoteOperation;
3940
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
4041
import com.owncloud.android.lib.common.utils.Log_OC;
@@ -50,6 +51,8 @@
5051
import androidx.recyclerview.widget.GridLayoutManager;
5152
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
5253
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
54+
import kotlin.Unit;
55+
import kotlin.jvm.functions.Function1;
5356

5457
/**
5558
* Activity listing pending, active, and completed uploads. User can delete completed uploads from view. Content of this
@@ -186,18 +189,21 @@ private void refresh() {
186189
backgroundJobManager,
187190
true);
188191

189-
if (uploadsStorageManager.getFailedUploads().length > 0) {
190-
new Thread(() -> {
191-
FileUploadHelper.Companion.instance().retryFailedUploads(
192-
uploadsStorageManager,
193-
connectivityService,
194-
accountManager,
195-
powerManagementService);
196-
uploadListAdapter.loadUploadItemsFromDb();
197-
}).start();
198-
DisplayUtils.showSnackMessage(this, R.string.uploader_local_files_uploaded);
199-
}
200-
192+
FileUploadHelper.Companion.instance().getUploadsByStatus(accountManager.getUser().getAccountName(), UploadsStorageManager.UploadStatus.UPLOAD_FAILED, new Function1<>() {
193+
@Override
194+
public Unit invoke(OCUpload[] ocUploads) {
195+
new Thread(() -> {
196+
FileUploadHelper.Companion.instance().retryFailedUploads(
197+
uploadsStorageManager,
198+
connectivityService,
199+
accountManager,
200+
powerManagementService);
201+
uploadListAdapter.loadUploadItemsFromDb();
202+
}).start();
203+
DisplayUtils.showSnackMessage(UploadListActivity.this, R.string.uploader_local_files_uploaded);
204+
return Unit.INSTANCE;
205+
}
206+
});
201207

202208
// update UI
203209
uploadListAdapter.loadUploadItemsFromDb(() -> swipeListRefreshLayout.setRefreshing(false));

0 commit comments

Comments
 (0)