From f6fbcbff629d67abf0bb67e5bc45cca9f1146286 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 18 Feb 2026 13:24:08 +0100 Subject: [PATCH 1/4] add auto upload logs Signed-off-by: alperozturk96 --- .../client/database/entity/UploadEntity.kt | 14 +++++ .../jobs/autoUpload/AutoUploadWorker.kt | 9 +++ .../network/ConnectivityServiceImpl.java | 45 +++++++++++++- .../extensions/SyncedFolderExtensions.kt | 61 +++++++++++++++++++ .../operations/UploadFileOperation.java | 25 ++++++-- 5 files changed, 149 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt b/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt index 7322a20e50a3..ff4ff9e91c6f 100644 --- a/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt +++ b/app/src/main/java/com/nextcloud/client/database/entity/UploadEntity.kt @@ -17,6 +17,7 @@ import com.owncloud.android.db.OCUpload import com.owncloud.android.db.ProviderMeta.ProviderTableMeta import com.owncloud.android.db.UploadResult import com.owncloud.android.files.services.NameCollisionPolicy +import com.owncloud.android.lib.common.utils.Log_OC import com.owncloud.android.lib.resources.status.OCCapability import java.lang.IllegalArgumentException @@ -71,6 +72,7 @@ fun UploadEntity.toOCUpload(capability: OCCapability? = null): OCUpload? { val upload = try { OCUpload(localPath, remotePath, accountName) } catch (_: IllegalArgumentException) { + Log_OC.e("UploadEntity", "OCUpload conversion failed") return null } @@ -92,9 +94,21 @@ fun UploadEntity.toOCUpload(capability: OCCapability? = null): OCUpload? { fun OCUpload.toUploadEntity(): UploadEntity { val id = if (uploadId == -1L) { + Log_OC.d( + "UploadEntity", + "UploadEntity: No existing ID provided (uploadId = -1). " + + "Will insert as NEW record and let Room auto-generate the primary key." + ) + // needed for the insert new records to the db so that insert DAO function returns new generated id null } else { + Log_OC.d( + "UploadEntity", + "UploadEntity: Using existing ID ($uploadId). " + + "This will update/replace the existing database record." + ) + uploadId } diff --git a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt index 01d78e1d9959..639a66ed8c75 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt @@ -23,6 +23,7 @@ import com.nextcloud.client.jobs.upload.FileUploadBroadcastManager import com.nextcloud.client.jobs.upload.FileUploadWorker import com.nextcloud.client.jobs.utils.UploadErrorNotificationManager import com.nextcloud.client.network.ConnectivityService +import com.nextcloud.utils.extensions.getLog import com.nextcloud.utils.extensions.isNonRetryable import com.nextcloud.utils.extensions.updateStatus import com.owncloud.android.R @@ -81,6 +82,8 @@ class AutoUploadWorker( syncedFolder = syncedFolderProvider.getSyncedFolderByID(syncFolderId) ?.takeIf { it.isEnabled } ?: return Result.failure() + Log_OC.d(TAG, syncedFolder.getLog()) + /** * Receives from [com.nextcloud.client.jobs.ContentObserverWork.checkAndTriggerAutoUpload] */ @@ -90,6 +93,10 @@ class AutoUploadWorker( return Result.retry() } + if (powerManagementService.isPowerSavingEnabled) { + Log_OC.w(TAG, "power saving mode enabled") + } + collectFileChangesFromContentObserverWork(contentUris) uploadFiles(syncedFolder) @@ -209,8 +216,10 @@ class AutoUploadWorker( withContext(Dispatchers.IO) { if (contentUris.isNullOrEmpty()) { + Log_OC.d(TAG, "inserting all entries") helper.insertEntries(syncedFolder, repository) } else { + Log_OC.d(TAG, "inserting changed entries") val isContentUrisStored = helper.insertChangedEntries(syncedFolder, contentUris, repository) if (!isContentUrisStored) { Log_OC.w( diff --git a/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java b/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java index 713cea72d5cc..c986e115b61c 100644 --- a/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java +++ b/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java @@ -71,6 +71,7 @@ public void isNetworkAndServerAvailable(@NonNull GenericCallback callba if (hasInternet) { result = !isInternetWalled(); } else { + Log_OC.e(TAG, "network and server not available"); result = false; } @@ -84,6 +85,7 @@ public boolean isConnected() { NetworkCapabilities actNw = platformConnectivityManager.getNetworkCapabilities(nw); if (actNw == null) { + Log_OC.e(TAG, "network capabilities is null"); return false; } @@ -101,6 +103,7 @@ public boolean isConnected() { return true; } + Log_OC.e(TAG, "network is not connected"); return false; } @@ -108,6 +111,10 @@ public boolean isConnected() { public boolean isInternetWalled() { final Boolean cachedValue = walledCheckCache.getValue(); if (cachedValue != null) { + if (cachedValue) { + Log_OC.e(TAG, "network is walled, cached value is used"); + } + return cachedValue; } else { Server server = accountManager.getUser().getServer(); @@ -116,6 +123,8 @@ public boolean isInternetWalled() { boolean result; Connectivity c = getConnectivity(); if (c != null && c.isConnected() && c.isWifi() && !c.isMetered() && !baseServerAddress.isEmpty()) { + Log_OC.d(TAG, "checking network status"); + GetMethod get = requestBuilder.invoke(baseServerAddress + CONNECTIVITY_CHECK_ROUTE); PlainClient client = clientFactory.createPlainClient(); @@ -129,9 +138,29 @@ public boolean isInternetWalled() { " assuming connectivity is impaired"); } } else { + Log_OC.e(TAG, "cannot check network status, connectivity is not eligible"); + + if (c != null) { + if (c.isMetered()) { + Log_OC.e(TAG, "network is metered"); + } + + if (!c.isWifi()) { + Log_OC.e(TAG, "network is not connected to wi-fi"); + } + + if (!c.isConnected()) { + Log_OC.e(TAG, "network is not connected"); + } + } + result = (c != null && !c.isConnected()); } + if (result) { + Log_OC.e(TAG, "network is walled"); + } + walledCheckCache.setValue(result); return result; } @@ -143,7 +172,8 @@ public Connectivity getConnectivity() { try { networkInfo = platformConnectivityManager.getActiveNetworkInfo(); } catch (Throwable t) { - networkInfo = null; // no network available or no information (permission denied?) + Log_OC.e(TAG, "no network available or no information: ", t); + networkInfo = null; } if (networkInfo != null) { @@ -152,6 +182,19 @@ public Connectivity getConnectivity() { boolean isMetered; isMetered = isNetworkMetered(); boolean isWifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI || hasNonCellularConnectivity(); + + if (!isMetered) { + Log_OC.w(TAG, "getConnectivity(): network is metered"); + } + + if (!isWifi) { + Log_OC.w(TAG, "getConnectivity(): network is not wi-fi"); + } + + if (!isConnected) { + Log_OC.e(TAG, "getConnectivity(): network is not connected"); + } + return new Connectivity(isConnected, isMetered, isWifi, null); } else { return Connectivity.DISCONNECTED; diff --git a/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt index 7f8cac806f2f..b4d309ae6893 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt @@ -11,6 +11,7 @@ import com.nextcloud.client.device.PowerManagementService import com.nextcloud.client.jobs.BackgroundJobManagerImpl import com.nextcloud.client.network.ConnectivityService import com.owncloud.android.R +import com.owncloud.android.datamodel.MediaFolderType import com.owncloud.android.datamodel.SyncedFolder import com.owncloud.android.datamodel.SyncedFolderDisplayItem import com.owncloud.android.lib.common.utils.Log_OC @@ -100,3 +101,63 @@ fun SyncedFolder.calculateScanInterval( else -> defaultIntervalMillis to null } } + +/** + * Builds a structured debug string of the SyncedFolder configuration. + * + * Important developer notes: + * + * uploadAction: + * Represents the UI option: + * 👉 "Original file will be..." + * (e.g., kept, deleted, moved after upload) + * + * nameCollisionPolicy: + * Represents the UI option: + * 👉 "What to do if the file already exists?" + * (e.g., rename, overwrite, skip) + * + * subfolderByDate: + * Represents the UI toggle: + * 👉 "Use subfolders" + * + * existing: + * Represents the UI option: + * 👉 "Also upload existing files" + * If false → only files created AFTER enabling are uploaded. + */ +fun SyncedFolder.getLog(): String { + val mediaType = when (type) { + MediaFolderType.IMAGE -> "🖼️ Images" + MediaFolderType.VIDEO -> "🎬 Videos" + MediaFolderType.CUSTOM -> "📁 Custom" + } + + return """ + 📦 Synced Folder + ───────────────────────── + 🆔 ID: $id + 👤 Account: $account + + 📂 Local: $localPath + ☁️ Remote: $remotePath + + $mediaType + 📅 Subfolder rule: ${subfolderRule ?: "None"} + 🗂️ By date: $isSubfolderByDate + 🙈 Exclude hidden: $isExcludeHidden + 👀 Hidden config: $isHidden + + 📶 Wi-Fi only: $isWifiOnly + 🔌 Charging only: $isChargingOnly + + 📤 Upload existing files: $isExisting + ⚙️ Upload action: $uploadAction + 🧩 Name collision: $nameCollisionPolicy + + ✅ Enabled: $isEnabled + 🕒 Enabled at: $enabledTimestampMs + 🔍 Last scan: $lastScanTimestampMs + ───────────────────────── + """.trimIndent() +} 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 ec5aa8f563c0..bae648167638 100644 --- a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -14,6 +14,7 @@ import android.content.Context; import android.net.Uri; import android.text.TextUtils; +import android.text.format.Formatter; import com.nextcloud.client.account.User; import com.nextcloud.client.device.BatteryStatus; @@ -1084,6 +1085,7 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) { if (!result.isSuccess()) return result; if (temporalFile.length() != originalFile.length()) { + Log_OC.e(TAG, "temporal file and original file lengths are not same - result is LOCK_FAILED"); result = new RemoteOperationResult<>(ResultCode.LOCK_FAILED); } filePath = temporalFile.toPath(); @@ -1115,24 +1117,30 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) { return result; } } + + final var formattedFileSize = Formatter.formatFileSize(mContext, size); updateSize(size); - Log_OC.d(TAG, "file size set to " + size); + Log_OC.d(TAG, "file size set to " + formattedFileSize); // decide whether chunked or not if (size > ChunkedFileUploadRemoteOperation.CHUNK_SIZE_MOBILE) { + Log_OC.d(TAG, "chunked upload operation will be used"); + boolean onWifiConnection = connectivityService.getConnectivity().isWifi(); mUploadOperation = new ChunkedFileUploadRemoteOperation( mFile.getStoragePath(), mFile.getRemotePath(), mFile.getMimeType(), mFile.getEtagInConflict(), lastModifiedTimestamp, creationTimestamp, onWifiConnection, mDisableRetries); } else { + Log_OC.d(TAG, "upload file operation will be used"); + mUploadOperation = new UploadFileRemoteOperation( mFile.getStoragePath(), mFile.getRemotePath(), mFile.getMimeType(), mFile.getEtagInConflict(), lastModifiedTimestamp, creationTimestamp, mDisableRetries); } - Log_OC.d(TAG, "upload operation determined"); + Log_OC.d(TAG, "upload type operation determined"); /** * Adds the onTransferProgress in FileUploadWorker @@ -1166,12 +1174,14 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) { } } } catch (FileNotFoundException e) { - Log_OC.e(TAG, mOriginalStoragePath + " not exists anymore"); + Log_OC.e(TAG, "normalupload(): file not found exception"); result = new RemoteOperationResult<>(ResultCode.LOCAL_FILE_NOT_FOUND); } catch (Exception e) { - Log_OC.e(TAG, "normal upload exception: ", e); + Log_OC.e(TAG, "normalupload(): exception: ", e); result = new RemoteOperationResult<>(e); } finally { + Log_OC.d(TAG, "normalupload(): finally block"); + mUploadStarted.set(false); // clean up temporal file if it exists @@ -1188,6 +1198,7 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) { } if (result == null) { + Log_OC.e(TAG, "result is null, UNKNOWN_ERROR"); result = new RemoteOperationResult<>(ResultCode.UNKNOWN_ERROR); } @@ -1201,6 +1212,8 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) { getStorageManager().saveConflict(mFile, mFile.getEtagInConflict()); } + Log_OC.d(TAG, "returning normalupload() result"); + return result; } @@ -1337,6 +1350,7 @@ private void handleLocalBehaviour(File temporalFile, switch (mLocalBehaviour) { case FileUploadWorker.LOCAL_BEHAVIOUR_DELETE: + Log_OC.d(TAG, "DELETE local behaviour will be handled"); try { Files.delete(originalFile.toPath()); } catch (IOException e) { @@ -1348,6 +1362,7 @@ private void handleLocalBehaviour(File temporalFile, break; case FileUploadWorker.LOCAL_BEHAVIOUR_COPY: + Log_OC.d(TAG, "COPY local behaviour will be handled"); if (temporalFile != null) { try { move(temporalFile, expectedFile); @@ -1372,6 +1387,7 @@ private void handleLocalBehaviour(File temporalFile, break; case FileUploadWorker.LOCAL_BEHAVIOUR_MOVE: + Log_OC.d(TAG, "MOVE local behaviour will be handled"); String expectedPath = FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), mFile); File newFile = new File(expectedPath); @@ -1389,6 +1405,7 @@ private void handleLocalBehaviour(File temporalFile, break; default: + Log_OC.d(TAG, "DEFAULT local behaviour will be handled"); mFile.setStoragePath(""); saveUploadedFile(client); break; From 80e7d977baba2575425b2368dcac5105731d6208 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 18 Feb 2026 13:27:56 +0100 Subject: [PATCH 2/4] add auto upload logs Signed-off-by: alperozturk96 --- .../com/nextcloud/client/network/ConnectivityServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java b/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java index c986e115b61c..ad6f07a0456b 100644 --- a/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java +++ b/app/src/main/java/com/nextcloud/client/network/ConnectivityServiceImpl.java @@ -183,7 +183,7 @@ public Connectivity getConnectivity() { isMetered = isNetworkMetered(); boolean isWifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI || hasNonCellularConnectivity(); - if (!isMetered) { + if (isMetered) { Log_OC.w(TAG, "getConnectivity(): network is metered"); } From 141e2098d82f0331e2429bdb61dba1bb9e640068 Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 18 Feb 2026 13:28:34 +0100 Subject: [PATCH 3/4] add auto upload logs Signed-off-by: alperozturk96 --- .../com/owncloud/android/operations/UploadFileOperation.java | 1 - 1 file changed, 1 deletion(-) 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 bae648167638..cfe827731dee 100644 --- a/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java +++ b/app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java @@ -1048,7 +1048,6 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) { return result; } - Log_OC.d(TAG, "checking name collision"); final var collisionResult = checkNameCollision(null, client, null, false); if (collisionResult != null) { Log_OC.e(TAG, "name collision detected"); From 4b8e810207af019860ea6fcd49c3b1f95fa9fc8f Mon Sep 17 00:00:00 2001 From: alperozturk96 Date: Wed, 18 Feb 2026 13:31:18 +0100 Subject: [PATCH 4/4] add auto upload logs Signed-off-by: alperozturk96 --- .../com/nextcloud/utils/extensions/SyncedFolderExtensions.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt b/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt index b4d309ae6893..991b9b0ee904 100644 --- a/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt +++ b/app/src/main/java/com/nextcloud/utils/extensions/SyncedFolderExtensions.kt @@ -105,8 +105,6 @@ fun SyncedFolder.calculateScanInterval( /** * Builds a structured debug string of the SyncedFolder configuration. * - * Important developer notes: - * * uploadAction: * Represents the UI option: * 👉 "Original file will be..."