Skip to content

Commit 03c3f4b

Browse files
committed
insert entries from content observer work
Signed-off-by: alperozturk96 <alper_ozturk@proton.me>
1 parent 50e9620 commit 03c3f4b

File tree

10 files changed

+72
-81
lines changed

10 files changed

+72
-81
lines changed

app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import com.nextcloud.client.device.PowerManagementService
2222
import com.nextcloud.client.documentscan.GeneratePDFUseCase
2323
import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork
2424
import com.nextcloud.client.integrations.deck.DeckApi
25+
import com.nextcloud.client.jobs.autoUpload.AutoUploadHelper
2526
import com.nextcloud.client.jobs.autoUpload.AutoUploadWorker
2627
import com.nextcloud.client.jobs.autoUpload.FileSystemRepository
2728
import com.nextcloud.client.jobs.download.FileDownloadWorker
@@ -132,7 +133,10 @@ class BackgroundJobFactory @Inject constructor(
132133
workerParameters,
133134
SyncedFolderProvider(contentResolver, preferences, clock),
134135
powerManagementService,
135-
backgroundJobManager.get()
136+
backgroundJobManager.get(),
137+
AutoUploadHelper(
138+
FileSystemRepository(dao = database.fileSystemDao(), uploadsStorageManager, context)
139+
)
136140
)
137141

138142
private fun createContactsBackupWork(context: Context, params: WorkerParameters): ContactsBackupWork =

app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ interface BackgroundJobManager {
122122

123123
fun startAutoUpload(
124124
syncedFolder: SyncedFolder,
125-
overridePowerSaving: Boolean = false,
126-
contentUris: Array<String?> = arrayOf()
125+
overridePowerSaving: Boolean = false
127126
)
128127

129128
fun cancelTwoWaySyncJob()
@@ -163,7 +162,6 @@ interface BackgroundJobManager {
163162
fun cancelAllJobs()
164163
fun schedulePeriodicHealthStatus()
165164
fun startHealthStatus()
166-
fun isAutoUploadWorkerRunning(syncedFolderID: Long): Boolean
167165
fun startOfflineOperations()
168166
fun startPeriodicallyOfflineOperation()
169167
fun scheduleInternal2WaySync(intervalMinutes: Long)

app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,10 +422,6 @@ internal class BackgroundJobManagerImpl(
422422
workManager.cancelJob(JOB_PERIODIC_CALENDAR_BACKUP, user)
423423
}
424424

425-
override fun isAutoUploadWorkerRunning(syncedFolderID: Long): Boolean =
426-
workManager.isWorkRunning(JOB_PERIODIC_FILES_SYNC + "_" + syncedFolderID) ||
427-
workManager.isWorkRunning(JOB_IMMEDIATE_FILES_SYNC + "_" + syncedFolderID)
428-
429425
override fun startPeriodicallyOfflineOperation() {
430426
val inputData = Data.Builder()
431427
.putString(OfflineOperationsWorker.JOB_NAME, JOB_PERIODIC_OFFLINE_OPERATIONS)
@@ -480,14 +476,12 @@ internal class BackgroundJobManagerImpl(
480476

481477
override fun startAutoUpload(
482478
syncedFolder: SyncedFolder,
483-
overridePowerSaving: Boolean,
484-
contentUris: Array<String?>
479+
overridePowerSaving: Boolean
485480
) {
486481
val syncedFolderID = syncedFolder.id
487482

488483
val arguments = Data.Builder()
489484
.putBoolean(AutoUploadWorker.OVERRIDE_POWER_SAVING, overridePowerSaving)
490-
.putStringArray(AutoUploadWorker.CONTENT_URIS, contentUris)
491485
.putLong(AutoUploadWorker.SYNCED_FOLDER_ID, syncedFolderID)
492486
.build()
493487

app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import android.content.Context
1111
import androidx.work.CoroutineWorker
1212
import androidx.work.WorkerParameters
1313
import com.nextcloud.client.device.PowerManagementService
14+
import com.nextcloud.client.jobs.autoUpload.AutoUploadHelper
1415
import com.owncloud.android.datamodel.SyncedFolderProvider
1516
import com.owncloud.android.lib.common.utils.Log_OC
1617
import com.owncloud.android.utils.FilesSyncHelper
@@ -29,7 +30,8 @@ class ContentObserverWork(
2930
private val params: WorkerParameters,
3031
private val syncedFolderProvider: SyncedFolderProvider,
3132
private val powerManagementService: PowerManagementService,
32-
private val backgroundJobManager: BackgroundJobManager
33+
private val backgroundJobManager: BackgroundJobManager,
34+
private val autoUploadHelper: AutoUploadHelper
3335
) : CoroutineWorker(context, params) {
3436

3537
companion object {
@@ -84,14 +86,33 @@ class ContentObserverWork(
8486
val contentUris = params.triggeredContentUris.map { uri ->
8587
// adds uri strings e.g. content://media/external/images/media/2281
8688
uri.toString()
87-
}.toTypedArray<String?>()
89+
}.toTypedArray<String>()
90+
8891
Log_OC.d(TAG, "📄 Content uris detected")
8992

9093
try {
94+
syncedFolderProvider.syncedFolders.forEach {
95+
if (it.isEnabled) {
96+
if (contentUris.isEmpty()) {
97+
Log_OC.d(TAG, "inserting all entries")
98+
autoUploadHelper.insertEntries(it)
99+
} else {
100+
Log_OC.d(TAG, "inserting changed entries")
101+
val isContentUrisStored = autoUploadHelper.insertChangedEntries(it, contentUris)
102+
if (!isContentUrisStored) {
103+
Log_OC.w(
104+
TAG,
105+
"changed content uris not stored, fallback to insert all db entries to not lose files"
106+
)
107+
autoUploadHelper.insertEntries(it)
108+
}
109+
}
110+
}
111+
}
112+
91113
FilesSyncHelper.startAutoUploadForEnabledSyncedFolders(
92114
syncedFolderProvider,
93115
backgroundJobManager,
94-
contentUris,
95116
false
96117
)
97118
Log_OC.d(TAG, "✅ auto upload triggered successfully for ${contentUris.size} file(s).")

app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadHelper.kt

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ import java.nio.file.SimpleFileVisitor
2424
import java.nio.file.attribute.BasicFileAttributes
2525

2626
@Suppress("TooGenericExceptionCaught", "MagicNumber", "ReturnCount")
27-
class AutoUploadHelper {
27+
class AutoUploadHelper(private val repository: FileSystemRepository) {
2828
companion object {
2929
private const val TAG = "AutoUploadHelper"
3030
private const val MAX_DEPTH = 100
3131
}
3232

33-
fun insertEntries(folder: SyncedFolder, repository: FileSystemRepository) {
33+
fun insertEntries(folder: SyncedFolder) {
3434
when (folder.type) {
3535
MediaFolderType.IMAGE -> {
3636
repository.insertFromUri(MediaStore.Images.Media.INTERNAL_CONTENT_URI, folder)
@@ -43,7 +43,7 @@ class AutoUploadHelper {
4343
}
4444

4545
else -> {
46-
insertCustomFolderIntoDB(folder, repository)
46+
insertCustomFolderIntoDB(folder)
4747
}
4848
}
4949
}
@@ -59,11 +59,7 @@ class AutoUploadHelper {
5959
* {@link ContentObserverWork##checkAndTriggerAutoUpload()}.
6060
* @return {@code true} if all changed content URIs were successfully stored; {@code false} otherwise.
6161
*/
62-
fun insertChangedEntries(
63-
syncedFolder: SyncedFolder,
64-
contentUris: Array<String>?,
65-
repository: FileSystemRepository
66-
): Boolean {
62+
fun insertChangedEntries(syncedFolder: SyncedFolder, contentUris: Array<String>?): Boolean {
6763
contentUris?.forEach { uriString ->
6864
try {
6965
val uri = uriString.toUri()
@@ -79,7 +75,7 @@ class AutoUploadHelper {
7975
return true
8076
}
8177

82-
fun insertCustomFolderIntoDB(folder: SyncedFolder, repository: FileSystemRepository): Int {
78+
fun insertCustomFolderIntoDB(folder: SyncedFolder): Int {
8379
val path = Paths.get(folder.localPath)
8480

8581
if (!Files.exists(path)) {

app/src/main/java/com/nextcloud/client/jobs/autoUpload/AutoUploadWorker.kt

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,10 @@ class AutoUploadWorker(
6767
companion object {
6868
const val TAG = "🔄📤" + "AutoUpload"
6969
const val OVERRIDE_POWER_SAVING = "overridePowerSaving"
70-
const val CONTENT_URIS = "content_uris"
7170
const val SYNCED_FOLDER_ID = "syncedFolderId"
7271
const val NOTIFICATION_ID = 266
7372
}
7473

75-
private val helper = AutoUploadHelper()
7674
private val syncFolderHelper = SyncFolderHelper(context)
7775
private val fileUploadBroadcastManager = FileUploadBroadcastManager(localBroadcastManager)
7876
private lateinit var syncedFolder: SyncedFolder
@@ -87,20 +85,15 @@ class AutoUploadWorker(
8785

8886
Log_OC.d(TAG, syncedFolder.getLog())
8987

90-
/**
91-
* Receives from [com.nextcloud.client.jobs.ContentObserverWork.checkAndTriggerAutoUpload]
92-
*/
93-
val contentUris = inputData.getStringArray(CONTENT_URIS)
9488

95-
if (canExitEarly(contentUris, syncFolderId)) {
89+
if (canExitEarly(syncFolderId)) {
9690
return Result.success()
9791
}
9892

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

103-
collectFileChangesFromContentObserverWork(contentUris)
10497
uploadFiles(syncedFolder)
10598

10699
// only update last scan time after uploading files
@@ -178,7 +171,7 @@ class AutoUploadWorker(
178171
}
179172

180173
@Suppress("ReturnCount")
181-
private fun canExitEarly(contentUris: Array<String>?, syncedFolderID: Long): Boolean {
174+
private fun canExitEarly(syncedFolderID: Long): Boolean {
182175
val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
183176
if ((powerManagementService.isPowerSavingEnabled && !overridePowerSaving)) {
184177
Log_OC.w(TAG, "⚡ Skipping: device is in power saving mode")
@@ -190,16 +183,11 @@ class AutoUploadWorker(
190183
return true
191184
}
192185

193-
if (backgroundJobManager.isAutoUploadWorkerRunning(syncedFolderID)) {
194-
Log_OC.w(TAG, "🚧 another worker is already running for $syncedFolderID")
195-
return true
196-
}
197-
198186
val totalScanInterval = syncedFolder.getTotalScanInterval(connectivityService, powerManagementService)
199187
val currentTime = System.currentTimeMillis()
200188
val passedScanInterval = totalScanInterval <= currentTime
201189

202-
if (!passedScanInterval && contentUris.isNullOrEmpty() && !overridePowerSaving) {
190+
if (!passedScanInterval && !overridePowerSaving) {
203191
Log_OC.w(
204192
TAG,
205193
"skipped since started before scan interval and nothing todo: " + syncedFolder.localPath
@@ -212,35 +200,6 @@ class AutoUploadWorker(
212200
return false
213201
}
214202

215-
/**
216-
* Instead of scanning the entire local folder, optional content URIs can be passed to the worker
217-
* to detect only the relevant changes.
218-
*/
219-
@Suppress("MagicNumber", "TooGenericExceptionCaught")
220-
private suspend fun collectFileChangesFromContentObserverWork(contentUris: Array<String>?) = try {
221-
Log_OC.d(TAG, "collecting file changes")
222-
223-
withContext(Dispatchers.IO) {
224-
if (contentUris.isNullOrEmpty()) {
225-
Log_OC.d(TAG, "inserting all entries")
226-
helper.insertEntries(syncedFolder, repository)
227-
} else {
228-
Log_OC.d(TAG, "inserting changed entries")
229-
val isContentUrisStored = helper.insertChangedEntries(syncedFolder, contentUris, repository)
230-
if (!isContentUrisStored) {
231-
Log_OC.w(
232-
TAG,
233-
"changed content uris not stored, fallback to insert all db entries to not lose files"
234-
)
235-
236-
helper.insertEntries(syncedFolder, repository)
237-
}
238-
}
239-
}
240-
} catch (e: Exception) {
241-
Log_OC.d(TAG, "Exception collectFileChangesFromContentObserverWork: $e")
242-
}
243-
244203
private fun getUserOrReturn(syncedFolder: SyncedFolder): User? {
245204
val optionalUser = userAccountManager.getUser(syncedFolder.account)
246205
if (!optionalUser.isPresent) {

app/src/main/java/com/owncloud/android/MainApp.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,6 @@ public void disableDocumentsStorageProvider() {
391391
if (preferences.startAutoUploadOnStart()) {
392392
FilesSyncHelper.startAutoUploadForEnabledSyncedFolders(syncedFolderProvider,
393393
backgroundJobManager,
394-
new String[]{},
395394
false);
396395
preferences.setLastAutoUploadOnStartTime(System.currentTimeMillis());
397396
}

app/src/main/java/com/owncloud/android/utils/FilesSyncHelper.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,13 @@ object FilesSyncHelper {
4242
fun startAutoUploadForEnabledSyncedFolders(
4343
provider: SyncedFolderProvider,
4444
manager: BackgroundJobManager,
45-
uris: Array<String?>,
4645
overridePowerSaving: Boolean
4746
) {
4847
Log_OC.d(TAG, "start auto upload worker for each enabled folder")
4948

5049
provider.syncedFolders.forEach {
5150
if (it.isEnabled) {
52-
manager.startAutoUpload(it, overridePowerSaving, uris)
51+
manager.startAutoUpload(it, overridePowerSaving)
5352
}
5453
}
5554
}

app/src/test/java/com/nextcloud/client/jobs/ContentObserverWorkTest.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,16 @@ package com.nextcloud.client.jobs
1111
import android.content.Context
1212
import android.net.Uri
1313
import androidx.work.WorkerParameters
14+
import com.nextcloud.client.database.dao.FileSystemDao
1415
import com.nextcloud.client.device.PowerManagementService
16+
import com.nextcloud.client.jobs.autoUpload.AutoUploadHelper
17+
import com.nextcloud.client.jobs.autoUpload.FileSystemRepository
1518
import com.owncloud.android.datamodel.SyncedFolderProvider
19+
import com.owncloud.android.datamodel.UploadsStorageManager
20+
import io.mockk.clearAllMocks
21+
import io.mockk.mockk
1622
import kotlinx.coroutines.runBlocking
23+
import org.junit.After
1724
import org.junit.Before
1825
import org.junit.Ignore
1926
import org.junit.Test
@@ -42,20 +49,34 @@ class ContentObserverWorkTest {
4249
@Mock
4350
lateinit var backgroundJobManager: BackgroundJobManager
4451

52+
private val mockDao: FileSystemDao = mockk(relaxed = true)
53+
private val mockContext: Context = mockk(relaxed = true)
54+
private val mockUploadsStorageManager: UploadsStorageManager = mockk(relaxed = true)
55+
4556
@Before
4657
fun setUp() {
4758
MockitoAnnotations.openMocks(this)
59+
60+
val repo = FileSystemRepository(mockDao, mockUploadsStorageManager, mockContext)
61+
val helper = AutoUploadHelper(repo)
62+
4863
worker = ContentObserverWork(
4964
context = context,
5065
params = params,
5166
syncedFolderProvider = folderProvider,
5267
powerManagementService = powerManagementService,
53-
backgroundJobManager = backgroundJobManager
68+
backgroundJobManager = backgroundJobManager,
69+
autoUploadHelper = helper
5470
)
5571
val uri: Uri = Mockito.mock(Uri::class.java)
5672
whenever(params.triggeredContentUris).thenReturn(listOf(uri))
5773
}
5874

75+
@After
76+
fun cleanup() {
77+
clearAllMocks()
78+
}
79+
5980
@Test
6081
fun job_reschedules_self_after_each_run_unconditionally() {
6182
runBlocking {

0 commit comments

Comments
 (0)