Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
}

Expand All @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
*/
Expand All @@ -90,6 +93,10 @@ class AutoUploadWorker(
return Result.retry()
}

if (powerManagementService.isPowerSavingEnabled) {
Log_OC.w(TAG, "power saving mode enabled")
}

collectFileChangesFromContentObserverWork(contentUris)
uploadFiles(syncedFolder)

Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public void isNetworkAndServerAvailable(@NonNull GenericCallback<Boolean> callba
if (hasInternet) {
result = !isInternetWalled();
} else {
Log_OC.e(TAG, "network and server not available");
result = false;
}

Expand All @@ -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;
}

Expand All @@ -101,13 +103,18 @@ public boolean isConnected() {
return true;
}

Log_OC.e(TAG, "network is not connected");
return false;
}

@Override
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();
Expand All @@ -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();

Expand All @@ -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;
}
Expand All @@ -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) {
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -100,3 +101,61 @@ fun SyncedFolder.calculateScanInterval(
else -> defaultIntervalMillis to null
}
}

/**
* Builds a structured debug string of the SyncedFolder configuration.
*
* 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()
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1047,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");
Expand Down Expand Up @@ -1084,6 +1084,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();
Expand Down Expand Up @@ -1115,24 +1116,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
Expand Down Expand Up @@ -1166,12 +1173,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
Expand All @@ -1188,6 +1197,7 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) {
}

if (result == null) {
Log_OC.e(TAG, "result is null, UNKNOWN_ERROR");
result = new RemoteOperationResult<>(ResultCode.UNKNOWN_ERROR);
}

Expand All @@ -1201,6 +1211,8 @@ private RemoteOperationResult normalUpload(OwnCloudClient client) {
getStorageManager().saveConflict(mFile, mFile.getEtagInConflict());
}

Log_OC.d(TAG, "returning normalupload() result");

return result;
}

Expand Down Expand Up @@ -1337,6 +1349,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) {
Expand All @@ -1348,6 +1361,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);
Expand All @@ -1372,6 +1386,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);

Expand All @@ -1389,6 +1404,7 @@ private void handleLocalBehaviour(File temporalFile,
break;

default:
Log_OC.d(TAG, "DEFAULT local behaviour will be handled");
mFile.setStoragePath("");
saveUploadedFile(client);
break;
Expand Down
Loading