Skip to content

Commit 9f53c14

Browse files
Merge pull request #16761 from nextcloud/upload-list-adapter-kt
refactor(upload-list-adapter): performance optimizations
2 parents fe2c76d + 0dbbaed commit 9f53c14

13 files changed

Lines changed: 1217 additions & 1237 deletions

File tree

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

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,9 @@ class FileUploadHelper {
124124
val capability = fileStorageManager.getCapability(accountManager.user)
125125

126126
try {
127-
getUploadsByStatus(null, UploadStatus.UPLOAD_FAILED, capability) {
128-
if (it.isNotEmpty()) {
127+
ioScope.launch {
128+
val uploads = getUploadsByStatus(null, UploadStatus.UPLOAD_FAILED, capability)
129+
if (uploads.isNotEmpty()) {
129130
isUploadStarted = true
130131
}
131132

@@ -134,7 +135,7 @@ class FileUploadHelper {
134135
connectivityService,
135136
accountManager,
136137
powerManagementService,
137-
uploads = it
138+
uploads
138139
)
139140
}
140141
} finally {
@@ -144,26 +145,21 @@ class FileUploadHelper {
144145
return isUploadStarted
145146
}
146147

147-
fun retryCancelledUploads(
148+
suspend fun retryCancelledUploads(
148149
uploadsStorageManager: UploadsStorageManager,
149150
connectivityService: ConnectivityService,
150151
accountManager: UserAccountManager,
151152
powerManagementService: PowerManagementService
152153
): Boolean {
153-
var result = false
154154
val capability = fileStorageManager.getCapability(accountManager.user)
155-
156-
getUploadsByStatus(accountManager.user.accountName, UploadStatus.UPLOAD_CANCELLED, capability) {
157-
result = retryUploads(
158-
uploadsStorageManager,
159-
connectivityService,
160-
accountManager,
161-
powerManagementService,
162-
it
163-
)
164-
}
165-
166-
return result
155+
val uploads = getUploadsByStatus(accountManager.user.accountName, UploadStatus.UPLOAD_CANCELLED, capability)
156+
return retryUploads(
157+
uploadsStorageManager,
158+
connectivityService,
159+
accountManager,
160+
powerManagementService,
161+
uploads
162+
)
167163
}
168164

169165
@Suppress("ComplexCondition")
@@ -172,7 +168,7 @@ class FileUploadHelper {
172168
connectivityService: ConnectivityService,
173169
accountManager: UserAccountManager,
174170
powerManagementService: PowerManagementService,
175-
uploads: Array<OCUpload>
171+
uploads: List<OCUpload>
176172
): Boolean {
177173
var showNotExistMessage = false
178174
var showSyncConflictNotification = false
@@ -343,31 +339,24 @@ class FileUploadHelper {
343339
* belonging to that account are retrieved. If [accountName] is `null`, uploads with the
344340
* given [status] from **all user accounts** are returned.
345341
*
346-
* Once the uploads are fetched, the [onCompleted] callback is invoked with the resulting array.
347-
*
348342
* @param accountName The name of the account to filter uploads by.
349343
* If `null`, uploads matching the given [status] from all accounts are returned.
350344
* @param status The [UploadStatus] to filter uploads by (e.g., `UPLOAD_FAILED`).
351345
* @param nameCollisionPolicy The [NameCollisionPolicy] to filter uploads by (e.g., `SKIP`).
352-
* @param onCompleted A callback invoked with the resulting array of [OCUpload] objects.
353346
*/
354-
fun getUploadsByStatus(
347+
suspend fun getUploadsByStatus(
355348
accountName: String?,
356349
status: UploadStatus,
357350
capability: OCCapability,
358-
nameCollisionPolicy: NameCollisionPolicy? = null,
359-
onCompleted: (Array<OCUpload>) -> Unit
360-
) {
361-
ioScope.launch {
362-
val dao = uploadsStorageManager.uploadDao
363-
val result = if (accountName != null) {
364-
dao.getUploadsByAccountNameAndStatus(accountName, status.value, nameCollisionPolicy?.serialize())
365-
} else {
366-
dao.getUploadsByStatus(status.value, nameCollisionPolicy?.serialize())
367-
}.mapNotNull {
368-
it.toOCUpload(capability)
369-
}.toTypedArray()
370-
onCompleted(result)
351+
nameCollisionPolicy: NameCollisionPolicy? = null
352+
): List<OCUpload> {
353+
val dao = uploadsStorageManager.uploadDao
354+
return if (accountName != null) {
355+
dao.getUploadsByAccountNameAndStatus(accountName, status.value, nameCollisionPolicy?.serialize())
356+
} else {
357+
dao.getUploadsByStatus(status.value, nameCollisionPolicy?.serialize())
358+
}.mapNotNull {
359+
it.toOCUpload(capability)
371360
}
372361
}
373362

app/src/main/java/com/nextcloud/utils/extensions/OCUploadExtensions.kt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,61 @@
77

88
package com.nextcloud.utils.extensions
99

10+
import android.content.Context
11+
import com.nextcloud.client.preferences.AppPreferences
12+
import com.owncloud.android.R
13+
import com.owncloud.android.datamodel.UploadsStorageManager
1014
import com.owncloud.android.db.OCUpload
15+
import com.owncloud.android.db.UploadResult
16+
import com.owncloud.android.files.services.NameCollisionPolicy
1117

1218
fun List<OCUpload>.getUploadIds(): LongArray = map { it.uploadId }.toLongArray()
1319

1420
fun Array<OCUpload>.getUploadIds(): LongArray = map { it.uploadId }.toLongArray()
21+
22+
fun List<OCUpload>.sortedByUploadOrder(): List<OCUpload> = sortedWith(
23+
compareBy<OCUpload> { it.fixedUploadStatus }
24+
.thenByDescending { it.isFixedUploadingNow }
25+
.thenByDescending { it.fixedUploadEndTimeStamp }
26+
.thenBy { it.fixedUploadId }
27+
)
28+
29+
fun OCUpload.getStatusText(activity: Context, isGlobalUploadPaused: Boolean, isUploading: Boolean): String {
30+
val status: String
31+
val res = activity.resources
32+
when (val uploadStatus = uploadStatus) {
33+
UploadsStorageManager.UploadStatus.UPLOAD_IN_PROGRESS -> {
34+
status = if (isGlobalUploadPaused) {
35+
res.getString(R.string.upload_global_pause_title)
36+
} else if (isUploading) {
37+
res.getString(R.string.uploader_upload_in_progress_ticker)
38+
} else {
39+
res.getString(R.string.uploads_view_later_waiting_to_upload)
40+
}
41+
}
42+
43+
UploadsStorageManager.UploadStatus.UPLOAD_SUCCEEDED -> {
44+
status = if (lastResult == UploadResult.SAME_FILE_CONFLICT) {
45+
res.getString(R.string.uploads_view_upload_status_succeeded_same_file)
46+
} else if (lastResult == UploadResult.FILE_NOT_FOUND) {
47+
lastResult.getFailedStatusText(activity)
48+
} else if (nameCollisionPolicy == NameCollisionPolicy.SKIP) {
49+
res.getString(R.string.uploads_view_upload_status_skip_reason)
50+
} else {
51+
res.getString(R.string.uploads_view_upload_status_succeeded)
52+
}
53+
}
54+
55+
UploadsStorageManager.UploadStatus.UPLOAD_FAILED ->
56+
status =
57+
lastResult.getFailedStatusText(activity)
58+
59+
UploadsStorageManager.UploadStatus.UPLOAD_CANCELLED ->
60+
status =
61+
res.getString(R.string.upload_manually_cancelled)
62+
63+
else -> status = "Uncontrolled status: $uploadStatus"
64+
}
65+
66+
return status
67+
}

app/src/main/java/com/nextcloud/utils/extensions/UploadResultExtensions.kt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
package com.nextcloud.utils.extensions
99

10+
import android.content.Context
11+
import com.owncloud.android.R
1012
import com.owncloud.android.db.UploadResult
1113

1214
fun UploadResult.isNonRetryable(): Boolean = when (this) {
@@ -32,3 +34,72 @@ fun UploadResult.isNonRetryable(): Boolean = when (this) {
3234
// everything else may succeed after retry
3335
else -> false
3436
}
37+
38+
fun UploadResult.getFailedStatusText(context: Context): String = when (this) {
39+
UploadResult.CREDENTIAL_ERROR ->
40+
context.getString(R.string.uploads_view_upload_status_failed_credentials_error)
41+
42+
UploadResult.FOLDER_ERROR ->
43+
context.getString(R.string.uploads_view_upload_status_failed_folder_error)
44+
45+
UploadResult.FILE_NOT_FOUND ->
46+
context.getString(R.string.uploads_view_upload_status_failed_localfile_error)
47+
48+
UploadResult.FILE_ERROR -> context.getString(R.string.uploads_view_upload_status_failed_file_error)
49+
50+
UploadResult.PRIVILEGES_ERROR -> context.getString(
51+
R.string.uploads_view_upload_status_failed_permission_error
52+
)
53+
54+
UploadResult.NETWORK_CONNECTION ->
55+
context.getString(R.string.uploads_view_upload_status_failed_connection_error)
56+
57+
UploadResult.DELAYED_FOR_WIFI -> context.getString(
58+
R.string.uploads_view_upload_status_waiting_for_wifi
59+
)
60+
61+
UploadResult.DELAYED_FOR_CHARGING ->
62+
context.getString(R.string.uploads_view_upload_status_waiting_for_charging)
63+
64+
UploadResult.CONFLICT_ERROR -> context.getString(R.string.uploads_view_upload_status_conflict)
65+
66+
UploadResult.SERVICE_INTERRUPTED -> context.getString(
67+
R.string.uploads_view_upload_status_service_interrupted
68+
)
69+
70+
UploadResult.CANCELLED -> // should not get here ; cancelled uploads should be wiped out
71+
context.getString(R.string.uploads_view_upload_status_cancelled)
72+
73+
UploadResult.UPLOADED -> // should not get here ; status should be UPLOAD_SUCCESS
74+
context.getString(R.string.uploads_view_upload_status_succeeded)
75+
76+
UploadResult.MAINTENANCE_MODE -> context.getString(R.string.maintenance_mode)
77+
78+
UploadResult.SSL_RECOVERABLE_PEER_UNVERIFIED -> context.getString(
79+
R.string.uploads_view_upload_status_failed_ssl_certificate_not_trusted
80+
)
81+
82+
UploadResult.UNKNOWN -> context.getString(R.string.uploads_view_upload_status_unknown_fail)
83+
84+
UploadResult.LOCK_FAILED -> context.getString(R.string.upload_lock_failed)
85+
86+
UploadResult.DELAYED_IN_POWER_SAVE_MODE -> context.getString(
87+
R.string.uploads_view_upload_status_waiting_exit_power_save_mode
88+
)
89+
90+
UploadResult.VIRUS_DETECTED -> context.getString(R.string.uploads_view_upload_status_virus_detected)
91+
92+
UploadResult.LOCAL_STORAGE_FULL -> context.getString(R.string.upload_local_storage_full)
93+
94+
UploadResult.OLD_ANDROID_API -> context.getString(R.string.upload_old_android)
95+
96+
UploadResult.SYNC_CONFLICT -> context.getString(R.string.upload_sync_conflict)
97+
98+
UploadResult.CANNOT_CREATE_FILE -> context.getString(R.string.upload_cannot_create_file)
99+
100+
UploadResult.LOCAL_STORAGE_NOT_COPIED -> context.getString(R.string.upload_local_storage_not_copied)
101+
102+
UploadResult.QUOTA_EXCEEDED -> context.getString(R.string.upload_quota_exceeded)
103+
104+
else -> context.getString(R.string.upload_unknown_error)
105+
}

app/src/main/java/com/owncloud/android/db/OCUploadComparator.kt

Lines changed: 0 additions & 59 deletions
This file was deleted.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public abstract class FileActivity extends DrawerActivity
175175
protected boolean isFileDisplayActivityResumed = false;
176176

177177
@Inject
178-
UserAccountManager accountManager;
178+
public UserAccountManager accountManager;
179179

180180
@Inject public ConnectivityService connectivityService;
181181

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
3838
import com.owncloud.android.lib.common.utils.Log_OC;
3939
import com.owncloud.android.operations.CheckCurrentCredentialsOperation;
40-
import com.owncloud.android.ui.adapter.UploadListAdapter;
40+
import com.owncloud.android.ui.adapter.uploadList.UploadListAdapter;
4141
import com.owncloud.android.ui.decoration.MediaGridItemDecoration;
4242
import com.owncloud.android.utils.FilesSyncHelper;
4343

@@ -317,7 +317,7 @@ public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationRe
317317
private class UploadFinishReceiver extends BroadcastReceiver {
318318
@Override
319319
public void onReceive(Context context, Intent intent) {
320-
throttler.run("update_upload_list", () -> uploadListAdapter.loadUploadItemsFromDb(() -> {}));
320+
throttler.run("update_upload_list", () -> uploadListAdapter.loadUploadItemsFromDb());
321321
}
322322
}
323323
}

0 commit comments

Comments
 (0)