Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix auto upload does not start automatically #12337

Merged
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
6 changes: 6 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,12 @@
</intent-filter>
</activity>

<service
android:name="androidx.work.impl.foreground.SystemForegroundService"
android:directBootAware="false"
android:enabled="@bool/enable_system_foreground_service_default"
android:exported="false"
android:foregroundServiceType="dataSync" />
<service
android:name=".services.OperationsService"
android:exported="false" />
Expand Down
40 changes: 36 additions & 4 deletions app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ package com.nextcloud.client.jobs
import android.content.ContentResolver
import android.content.Context
import android.content.res.Resources
import android.os.Build
import android.text.TextUtils
import androidx.core.app.NotificationCompat
import androidx.exifinterface.media.ExifInterface
import androidx.work.Worker
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.nextcloud.client.account.UserAccountManager
import com.nextcloud.client.device.PowerManagementService
Expand All @@ -37,6 +40,7 @@ import com.owncloud.android.R
import com.owncloud.android.datamodel.ArbitraryDataProvider
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
import com.owncloud.android.datamodel.FilesystemDataProvider
import com.owncloud.android.datamodel.ForegroundServiceType
import com.owncloud.android.datamodel.MediaFolderType
import com.owncloud.android.datamodel.SyncedFolder
import com.owncloud.android.datamodel.SyncedFolderProvider
Expand All @@ -45,6 +49,7 @@ import com.owncloud.android.files.services.FileUploader
import com.owncloud.android.lib.common.utils.Log_OC
import com.owncloud.android.operations.UploadFileOperation
import com.owncloud.android.ui.activity.SettingsActivity
import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.utils.FileStorageUtils
import com.owncloud.android.utils.FilesSyncHelper
import com.owncloud.android.utils.MimeType
Expand All @@ -66,16 +71,38 @@ class FilesSyncWork(
private val powerManagementService: PowerManagementService,
private val syncedFolderProvider: SyncedFolderProvider,
private val backgroundJobManager: BackgroundJobManager
) : Worker(context, params) {
) : CoroutineWorker(context, params) {

companion object {
const val TAG = "FilesSyncJob"
const val SKIP_CUSTOM = "skipCustom"
const val OVERRIDE_POWER_SAVING = "overridePowerSaving"
const val FOREGROUND_SERVICE_ID = 414
}

override fun doWork(): Result {
@Suppress("MagicNumber")
private fun createForegroundInfo(progressPercent: Int): ForegroundInfo {
// update throughout worker execution to give use feedback how far worker is

val notification = NotificationCompat.Builder(context, NotificationUtils.NOTIFICATION_CHANNEL_FILE_SYNC)
.setTicker(context.getString(R.string.autoupload_worker_foreground_info))
.setContentText(context.getString(R.string.autoupload_worker_foreground_info))
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle(context.getString(R.string.autoupload_worker_foreground_info))
.setOngoing(true)
.setProgress(100, progressPercent, false)
.build()
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ForegroundInfo(FOREGROUND_SERVICE_ID, notification, ForegroundServiceType.DataSync.getId())
} else {
ForegroundInfo(FOREGROUND_SERVICE_ID, notification)
}
}

@Suppress("MagicNumber")
override suspend fun doWork(): Result {
backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
setForeground(createForegroundInfo(0))

val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
// If we are in power save mode, better to postpone upload
Expand All @@ -93,13 +120,18 @@ class FilesSyncWork(
connectivityService,
powerManagementService
)
setForeground(createForegroundInfo(5))
FilesSyncHelper.insertAllDBEntries(skipCustom, syncedFolderProvider)
setForeground(createForegroundInfo(50))
// Create all the providers we'll need
val filesystemDataProvider = FilesystemDataProvider(contentResolver)
val currentLocale = resources.configuration.locale
val dateFormat = SimpleDateFormat("yyyy:MM:dd HH:mm:ss", currentLocale)
dateFormat.timeZone = TimeZone.getTimeZone(TimeZone.getDefault().id)
for (syncedFolder in syncedFolderProvider.syncedFolders) {

val syncedFolders = syncedFolderProvider.syncedFolders
for ((index, syncedFolder) in syncedFolders.withIndex()) {
setForeground(createForegroundInfo((50 + (index.toDouble() / syncedFolders.size.toDouble()) * 50).toInt()))
if (syncedFolder.isEnabled && (!skipCustom || MediaFolderType.CUSTOM != syncedFolder.type)) {
syncFolder(
context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,23 +55,23 @@ public FilesystemDataProvider(ContentResolver contentResolver) {

public int deleteAllEntriesForSyncedFolder(String syncedFolderId) {
return contentResolver.delete(
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
new String[]{syncedFolderId}
);
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
new String[]{syncedFolderId}
);
}

public void updateFilesystemFileAsSentForUpload(String path, String syncedFolderId) {
ContentValues cv = new ContentValues();
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, 1);

contentResolver.update(
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
cv,
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
new String[]{path, syncedFolderId}
);
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
cv,
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
new String[]{path, syncedFolderId}
);
}

public Set<String> getFilesForUpload(String localPath, String syncedFolderId) {
Expand All @@ -80,20 +80,20 @@ public Set<String> getFilesForUpload(String localPath, String syncedFolderId) {
String likeParam = localPath + "%";

Cursor cursor = contentResolver.query(
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
null,
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " LIKE ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER + " = ?",
new String[]{likeParam, syncedFolderId, "0", "0"},
null);
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
null,
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " LIKE ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER + " = ?",
new String[]{likeParam, syncedFolderId, "0", "0"},
null);

if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String value = cursor.getString(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
if (value == null) {
Log_OC.e(TAG, "Cannot get local path");
} else {
Expand Down Expand Up @@ -159,11 +159,11 @@ public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean is


int result = contentResolver.update(
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
cv,
ProviderMeta.ProviderTableMeta._ID + "=?",
new String[]{String.valueOf(data.getId())}
);
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
cv,
ProviderMeta.ProviderTableMeta._ID + "=?",
new String[]{String.valueOf(data.getId())}
);

if (result == 0) {
Log_OC.v(TAG, "Failed to update filesystem data with local path: " + localPath);
Expand All @@ -174,33 +174,33 @@ public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean is
private FileSystemDataSet getFilesystemDataSet(String localPathParam, SyncedFolder syncedFolder) {

Cursor cursor = contentResolver.query(
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
null,
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
new String[]{localPathParam, Long.toString(syncedFolder.getId())},
null
);
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
null,
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
new String[]{localPathParam, Long.toString(syncedFolder.getId())},
null
);

FileSystemDataSet dataSet = null;
if (cursor != null) {
if (cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta._ID));
String localPath = cursor.getString(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
long modifiedAt = cursor.getLong(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED));
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED));
boolean isFolder = false;
if (cursor.getInt(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER)) != 0) {
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER)) != 0) {
isFolder = true;
}
long foundAt = cursor.getLong(cursor.getColumnIndexOrThrow(ProviderMeta.
ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY));
ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY));

boolean isSentForUpload = false;
if (cursor.getInt(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD)) != 0) {
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD)) != 0) {
isSentForUpload = true;
}

Expand All @@ -210,7 +210,7 @@ private FileSystemDataSet getFilesystemDataSet(String localPathParam, SyncedFold
Log_OC.e(TAG, "Arbitrary value could not be created from cursor");
} else {
dataSet = new FileSystemDataSet(id, localPath, modifiedAt, isFolder, isSentForUpload, foundAt,
syncedFolder.getId(), crc32);
syncedFolder.getId(), crc32);
}
}
cursor.close();
Expand All @@ -223,11 +223,12 @@ private FileSystemDataSet getFilesystemDataSet(String localPathParam, SyncedFold

private long getFileChecksum(String filepath) {

try (InputStream inputStream = new BufferedInputStream(new FileInputStream(filepath))){
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(filepath))) {
CRC32 crc = new CRC32();
int cnt;
while ((cnt = inputStream.read()) != -1) {
crc.update(cnt);
byte[] buf = new byte[1024 * 64];
int size;
while ((size = inputStream.read(buf)) > 0) {
crc.update(buf, 0, size);
}

return crc.getValue();
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@
<string name="autoupload_hide_folder">Hide folder</string>
<string name="autoupload_configure">Configure</string>
<string name="synced_folders_configure_folders">Configure folders</string>
<string name="autoupload_worker_foreground_info">Preparing auto upload</string>

<string name="empty" translatable="false" />
<string name="test_server_button">Test server connection</string>
Expand Down
Loading