From 74afb1f721dab9db9de8b592164924ad04f294c7 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 25 Oct 2023 14:50:19 +0200 Subject: [PATCH 01/20] add periodicScan package over contentScanner --- .../e/drive/operations/ListFileRemoteOperation.java | 8 ++------ .../contentScanner/AbstractContentScanner.java | 2 +- .../contentScanner/AbstractFileLister.java | 2 +- .../{ => periodicScan}/contentScanner/FileDiffUtils.kt | 2 +- .../{ => periodicScan}/contentScanner/FolderWrapper.java | 2 +- .../contentScanner/LocalContentScanner.java | 2 +- .../contentScanner/LocalFileLister.java | 2 +- .../contentScanner/RemoteContentScanner.java | 4 ++-- .../contentScanner/RemoteFileLister.java | 2 +- .../java/foundation/e/drive/services/ObserverService.java | 6 +++--- .../contentScanner/FileDiffUtilsTest.kt | 3 ++- .../contentScanner/LocalContentScannerTest.java | 3 ++- .../contentScanner/LocalFileListerTest.java | 4 +++- .../contentScanner/RemoteContentScannerTest.java | 3 ++- .../contentScanner/RemoteFileListerTest.java | 3 ++- 15 files changed, 25 insertions(+), 23 deletions(-) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/AbstractContentScanner.java (98%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/AbstractFileLister.java (99%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/FileDiffUtils.kt (98%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/FolderWrapper.java (97%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/LocalContentScanner.java (98%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/LocalFileLister.java (98%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/RemoteContentScanner.java (97%) rename app/src/main/java/foundation/e/drive/{ => periodicScan}/contentScanner/RemoteFileLister.java (98%) rename app/src/test/java/foundation/e/drive/{ => periodicScan}/contentScanner/FileDiffUtilsTest.kt (99%) rename app/src/test/java/foundation/e/drive/{ => periodicScan}/contentScanner/LocalContentScannerTest.java (98%) rename app/src/test/java/foundation/e/drive/{ => periodicScan}/contentScanner/LocalFileListerTest.java (98%) rename app/src/test/java/foundation/e/drive/{ => periodicScan}/contentScanner/RemoteContentScannerTest.java (98%) rename app/src/test/java/foundation/e/drive/{ => periodicScan}/contentScanner/RemoteFileListerTest.java (99%) diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java index c5aa5ec6..46dadfe4 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java @@ -12,22 +12,18 @@ package foundation.e.drive.operations; import android.content.Context; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import com.owncloud.android.lib.common.OwnCloudClient; import com.owncloud.android.lib.common.operations.RemoteOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult; -import com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation; import com.owncloud.android.lib.resources.files.model.RemoteFile; -import java.io.File; + import java.util.ArrayList; import java.util.List; -import java.util.ListIterator; -import foundation.e.drive.contentScanner.RemoteFileLister; +import foundation.e.drive.periodicScan.contentScanner.RemoteFileLister; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFolder; -import foundation.e.drive.utils.CommonUtils; import timber.log.Timber; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/AbstractContentScanner.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/AbstractContentScanner.java similarity index 98% rename from app/src/main/java/foundation/e/drive/contentScanner/AbstractContentScanner.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/AbstractContentScanner.java index c8b843c9..6bb3deb2 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/AbstractContentScanner.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/AbstractContentScanner.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import android.content.Context; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/AbstractFileLister.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/AbstractFileLister.java similarity index 99% rename from app/src/main/java/foundation/e/drive/contentScanner/AbstractFileLister.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/AbstractFileLister.java index 0e45cdcd..da8a6cb7 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/AbstractFileLister.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/AbstractFileLister.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import android.content.Context; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/FileDiffUtils.kt b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/FileDiffUtils.kt similarity index 98% rename from app/src/main/java/foundation/e/drive/contentScanner/FileDiffUtils.kt rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/FileDiffUtils.kt index 273dfe5c..41e34693 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/FileDiffUtils.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/FileDiffUtils.kt @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner +package foundation.e.drive.periodicScan.contentScanner import androidx.annotation.VisibleForTesting import com.owncloud.android.lib.resources.files.model.RemoteFile diff --git a/app/src/main/java/foundation/e/drive/contentScanner/FolderWrapper.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/FolderWrapper.java similarity index 97% rename from app/src/main/java/foundation/e/drive/contentScanner/FolderWrapper.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/FolderWrapper.java index 49a5ee37..4c9bb0bc 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/FolderWrapper.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/FolderWrapper.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import androidx.annotation.NonNull; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/LocalContentScanner.java similarity index 98% rename from app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/LocalContentScanner.java index 6e62d02d..83a656fa 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/LocalContentScanner.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/LocalContentScanner.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import static foundation.e.drive.models.SyncedFileStateKt.DO_NOT_SCAN; import static foundation.e.drive.models.SyncedFileStateKt.SCAN_ON_CLOUD; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/LocalFileLister.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/LocalFileLister.java similarity index 98% rename from app/src/main/java/foundation/e/drive/contentScanner/LocalFileLister.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/LocalFileLister.java index 80a9fa8e..11d2c58d 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/LocalFileLister.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/LocalFileLister.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import android.content.Context; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/RemoteContentScanner.java similarity index 97% rename from app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/RemoteContentScanner.java index 3848eb89..d4f22e74 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/RemoteContentScanner.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/RemoteContentScanner.java @@ -5,13 +5,13 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import static foundation.e.drive.models.SyncRequest.Type.DISABLE_SYNCING; import static foundation.e.drive.models.SyncedFileStateKt.DO_NOT_SCAN; import static foundation.e.drive.models.SyncedFileStateKt.SCAN_ON_CLOUD; import static foundation.e.drive.models.SyncedFileStateKt.SCAN_ON_DEVICE; -import static foundation.e.drive.contentScanner.FileDiffUtils.getActionForFileDiff; +import static foundation.e.drive.periodicScan.contentScanner.FileDiffUtils.getActionForFileDiff; import android.content.Context; diff --git a/app/src/main/java/foundation/e/drive/contentScanner/RemoteFileLister.java b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/RemoteFileLister.java similarity index 98% rename from app/src/main/java/foundation/e/drive/contentScanner/RemoteFileLister.java rename to app/src/main/java/foundation/e/drive/periodicScan/contentScanner/RemoteFileLister.java index 8c54a649..de99d1c6 100644 --- a/app/src/main/java/foundation/e/drive/contentScanner/RemoteFileLister.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/contentScanner/RemoteFileLister.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import android.content.Context; diff --git a/app/src/main/java/foundation/e/drive/services/ObserverService.java b/app/src/main/java/foundation/e/drive/services/ObserverService.java index fe8faf1a..0d03f998 100644 --- a/app/src/main/java/foundation/e/drive/services/ObserverService.java +++ b/app/src/main/java/foundation/e/drive/services/ObserverService.java @@ -36,9 +36,9 @@ import java.util.HashMap; import java.util.List; import foundation.e.drive.R; -import foundation.e.drive.contentScanner.LocalContentScanner; -import foundation.e.drive.contentScanner.LocalFileLister; -import foundation.e.drive.contentScanner.RemoteContentScanner; +import foundation.e.drive.periodicScan.contentScanner.LocalContentScanner; +import foundation.e.drive.periodicScan.contentScanner.LocalFileLister; +import foundation.e.drive.periodicScan.contentScanner.RemoteContentScanner; import foundation.e.drive.database.DbHelper; import foundation.e.drive.fileFilters.CrashlogsFileFilter; import foundation.e.drive.fileFilters.OnlyFileFilter; diff --git a/app/src/test/java/foundation/e/drive/contentScanner/FileDiffUtilsTest.kt b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/FileDiffUtilsTest.kt similarity index 99% rename from app/src/test/java/foundation/e/drive/contentScanner/FileDiffUtilsTest.kt rename to app/src/test/java/foundation/e/drive/periodicScan/contentScanner/FileDiffUtilsTest.kt index 8bae8a20..f078df1d 100644 --- a/app/src/test/java/foundation/e/drive/contentScanner/FileDiffUtilsTest.kt +++ b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/FileDiffUtilsTest.kt @@ -5,10 +5,11 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner +package foundation.e.drive.periodicScan.contentScanner import com.owncloud.android.lib.resources.files.model.RemoteFile import foundation.e.drive.models.SyncedFileState +import foundation.e.drive.periodicScan.contentScanner.FileDiffUtils import org.junit.Assert import org.junit.Test import org.mockito.Mockito diff --git a/app/src/test/java/foundation/e/drive/contentScanner/LocalContentScannerTest.java b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/LocalContentScannerTest.java similarity index 98% rename from app/src/test/java/foundation/e/drive/contentScanner/LocalContentScannerTest.java rename to app/src/test/java/foundation/e/drive/periodicScan/contentScanner/LocalContentScannerTest.java index e57efbf6..6468357a 100644 --- a/app/src/test/java/foundation/e/drive/contentScanner/LocalContentScannerTest.java +++ b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/LocalContentScannerTest.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import static org.mockito.Mockito.when; import static foundation.e.drive.models.SyncedFileStateKt.SCAN_EVERYWHERE; @@ -33,6 +33,7 @@ import java.util.List; import foundation.e.drive.models.SyncRequest; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; +import foundation.e.drive.periodicScan.contentScanner.LocalContentScanner; /** * @author vincent Bourgmayer diff --git a/app/src/test/java/foundation/e/drive/contentScanner/LocalFileListerTest.java b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/LocalFileListerTest.java similarity index 98% rename from app/src/test/java/foundation/e/drive/contentScanner/LocalFileListerTest.java rename to app/src/test/java/foundation/e/drive/periodicScan/contentScanner/LocalFileListerTest.java index 40e41d2c..38a69070 100644 --- a/app/src/test/java/foundation/e/drive/contentScanner/LocalFileListerTest.java +++ b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/LocalFileListerTest.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import static foundation.e.drive.models.SyncedFileStateKt.SCAN_EVERYWHERE; @@ -36,6 +36,8 @@ import foundation.e.drive.TestUtils; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; +import foundation.e.drive.periodicScan.contentScanner.FolderWrapper; +import foundation.e.drive.periodicScan.contentScanner.LocalFileLister; /** * @author vincent Bourgmayer diff --git a/app/src/test/java/foundation/e/drive/contentScanner/RemoteContentScannerTest.java b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/RemoteContentScannerTest.java similarity index 98% rename from app/src/test/java/foundation/e/drive/contentScanner/RemoteContentScannerTest.java rename to app/src/test/java/foundation/e/drive/periodicScan/contentScanner/RemoteContentScannerTest.java index 476d9616..a985db22 100644 --- a/app/src/test/java/foundation/e/drive/contentScanner/RemoteContentScannerTest.java +++ b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/RemoteContentScannerTest.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import static org.junit.Assert.assertEquals; @@ -36,6 +36,7 @@ import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncRequest; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; +import foundation.e.drive.periodicScan.contentScanner.RemoteContentScanner; /** * @author vincent Bourgmayer diff --git a/app/src/test/java/foundation/e/drive/contentScanner/RemoteFileListerTest.java b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/RemoteFileListerTest.java similarity index 99% rename from app/src/test/java/foundation/e/drive/contentScanner/RemoteFileListerTest.java rename to app/src/test/java/foundation/e/drive/periodicScan/contentScanner/RemoteFileListerTest.java index c421c8a7..2f4c9e7a 100644 --- a/app/src/test/java/foundation/e/drive/contentScanner/RemoteFileListerTest.java +++ b/app/src/test/java/foundation/e/drive/periodicScan/contentScanner/RemoteFileListerTest.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.contentScanner; +package foundation.e.drive.periodicScan.contentScanner; import static org.mockito.Mockito.when; @@ -41,6 +41,7 @@ import foundation.e.drive.TestUtils; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFileState; import foundation.e.drive.models.SyncedFolder; +import foundation.e.drive.periodicScan.contentScanner.RemoteFileLister; import foundation.e.drive.utils.DavClientProvider; /** -- GitLab From e2b60e95e4e5bc9446ff059957b245983019dabf Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 25 Oct 2023 16:03:55 +0200 Subject: [PATCH 02/20] implement worker to replace ObserverService --- .../drive/periodicScan/PeriodicScanWorker.kt | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt diff --git a/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt new file mode 100644 index 00000000..665639e2 --- /dev/null +++ b/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt @@ -0,0 +1,209 @@ +/* + * Copyright © MURENA SAS 2023. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0 + * which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/gpl.html + */ +package foundation.e.drive.periodicScan + +import android.accounts.Account +import android.accounts.AccountManager +import android.app.Application +import android.content.Context +import android.content.SharedPreferences +import androidx.work.Worker +import androidx.work.WorkerParameters +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.resources.files.model.RemoteFile +import foundation.e.drive.R +import foundation.e.drive.database.DbHelper +import foundation.e.drive.models.SyncRequest +import foundation.e.drive.models.SyncedFolder +import foundation.e.drive.operations.ListFileRemoteOperation +import foundation.e.drive.periodicScan.contentScanner.LocalContentScanner +import foundation.e.drive.periodicScan.contentScanner.LocalFileLister +import foundation.e.drive.periodicScan.contentScanner.RemoteContentScanner +import foundation.e.drive.synchronization.SyncProxy +import foundation.e.drive.synchronization.SyncRequestCollector +import foundation.e.drive.utils.AppConstants +import foundation.e.drive.utils.CommonUtils +import foundation.e.drive.utils.DavClientProvider +import timber.log.Timber +import java.util.ArrayList + +class PeriodicScanWorker(private val context: Context, private val workerParams: WorkerParameters) : + Worker(context, workerParams) +{ + + private val syncRequests = HashMap() + + companion object { + private const val SYNC_MINIMUM_DELAY = 900000 // min delay between two run in ms. + const val ACTION_FORCED_SYNC_KEY = "forced_sync" + } + + override fun doWork(): Result { + val requestCollector: SyncRequestCollector = SyncProxy + + val prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) + val account = loadAccount(prefs) + + val startAllowed = checkStartConditions(account, prefs, requestCollector) + if (!startAllowed) { + Timber.d("Start Periodic Scan is not allowed") + requestCollector.startListeningFiles(applicationContext as Application) + return Result.failure() + } + + val syncFolders = loadSyncedFolders(account!!) + if (syncFolders.isEmpty()) { + requestCollector.startListeningFiles(applicationContext as Application) + return Result.success() + } + + val remoteSyncRequest = scanRemoteFiles(account, syncFolders.toMutableList()) + syncRequests.putAll(remoteSyncRequest) + + val localSyncRequest = scanLocalFiles(syncFolders.toMutableList()) + syncRequests.putAll(localSyncRequest) + + if (syncRequests.isEmpty()) { + requestCollector.startListeningFiles(applicationContext as Application) + return Result.success() + } + requestCollector.queueSyncRequests(syncRequests.values, context) + requestCollector.startSynchronization(applicationContext) + return Result.success() + } + + /** + * Check conditions to start periodic scan are respected + */ + private fun checkStartConditions(account: Account?, prefs : SharedPreferences, requestCollector: SyncRequestCollector): Boolean { + Timber.d("PeriodicScanWorker.checkStartConditions()") + + if (!isSetupDone(prefs)) return false + + if (account == null) return false + + if (isFileSyncDisabled(account)) return false //@todo could be replaced by checking list of sync folders not empty after loading them + + val forcedSync = workerParams.inputData.getBoolean(ACTION_FORCED_SYNC_KEY, false) + + if (!forcedSync && !isMinimumDelayRespected(prefs)) return false + + if (!isConnectedToAllowedNetwork(account)) return false + + if (!requestCollector.onPeriodicScanStart(applicationContext as Application)) return false + + return true + } + + private fun loadAccount(prefs: SharedPreferences): Account? { + val accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, "") ?: return null + val accountType = context.getString(R.string.eelo_account_type) + + return CommonUtils.getAccount(accountName, accountType, AccountManager.get(context)) + } + + /** + * indicate if minimum delay between two periodic scan is respected + */ + private fun isMinimumDelayRespected(prefs: SharedPreferences): Boolean { + val lastSyncTime = prefs.getLong(AppConstants.KEY_LAST_SYNC_TIME, 0L) + val currentTime = System.currentTimeMillis() + val deltaTime = currentTime - lastSyncTime + + return deltaTime >= SYNC_MINIMUM_DELAY + } + + /** + * Indicates if user has disable both media and settings files synchronization + */ + private fun isFileSyncDisabled(account: Account) : Boolean { + return !CommonUtils.isMediaSyncEnabled(account) && !CommonUtils.isSettingsSyncEnabled(account) + } + + /** + * Indicates if account has been set up and Remote root folders created + */ + private fun isSetupDone(prefs: SharedPreferences): Boolean { + return prefs.getBoolean(AppConstants.SETUP_COMPLETED, false) + } + + /** + * Check if device is connected to an allowed network type for synchronization + * note: because user can disable sync over metered network + */ + private fun isConnectedToAllowedNetwork(account: Account): Boolean { + val isMeteredNetworkAllowed = CommonUtils.isMeteredNetworkAllowed(account) + return CommonUtils.haveNetworkConnection(context, isMeteredNetworkAllowed) + } + + /** + * Fetch SyncedFolders list from Database + */ + private fun loadSyncedFolders(account: Account): List { + val isMediaSyncEnabled = CommonUtils.isMediaSyncEnabled(account) + val isSettingsSyncEnabled = CommonUtils.isSettingsSyncEnabled(account) + + return if (isMediaSyncEnabled && isSettingsSyncEnabled) DbHelper.getAllSyncedFolders(context) + else if (isMediaSyncEnabled) DbHelper.getSyncedFolderList(context, true) + else if (isSettingsSyncEnabled) DbHelper.getSyncedFolderList(context, false) + else ArrayList() + } + + /** + * generate SyncRequest for files on the cloud + */ + private fun scanRemoteFiles(account: Account, syncedFolders: List): HashMap { + val ocClient = DavClientProvider.getInstance().getClientInstance(account, context)?: return HashMap() + val listRemoteFilesOperation = ListFileRemoteOperation(syncedFolders, context) + + try { + @Suppress("DEPRECATION") + val result = listRemoteFilesOperation.execute(ocClient) as RemoteOperationResult> + if (!result.isSuccess) { + Timber.d("Fails to check remote files") + } + val remoteFiles = result.resultData as List + + val syncedFoldersIds = listRemoteFilesOperation.syncedFoldersId + val syncedFileStates = DbHelper.getSyncedFileStatesByFolders(context, syncedFoldersIds) + + if (remoteFiles.isNotEmpty() && syncedFileStates.isNotEmpty()) { + val scanner = RemoteContentScanner(context, syncedFolders) + return scanner.scanContent(remoteFiles, syncedFileStates) + } + + } catch(exception: IllegalArgumentException) { + Timber.e(exception) + } + return HashMap() + } + + /** + * generate SyncRequest for files on the device + */ + private fun scanLocalFiles(syncedFolders: List): HashMap { + val localFileLister = LocalFileLister(syncedFolders) + val isContentToScan = localFileLister.listContentToScan(context) + + if(!isContentToScan) { + return HashMap() + } + + val localFiles = localFileLister.contentToScan + val syncedFoldersIds = localFileLister.syncedFoldersId + val syncedFileStates = DbHelper.getSyncedFileStatesByFolders(context, syncedFoldersIds) + + if (localFiles.isNotEmpty() && syncedFileStates.isNotEmpty()) { + val scanner = LocalContentScanner(context, syncedFolders) + return scanner.scanContent(localFiles, syncedFileStates) + } + return HashMap() + } + + +} \ No newline at end of file -- GitLab From 393ac91f26c63174ef3be811d92c4d6823a320aa Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 25 Oct 2023 16:46:51 +0200 Subject: [PATCH 03/20] remove ObserverService & FullScanWorker --- app/src/main/AndroidManifest.xml | 3 - .../AccountRemoveCallbackReceiver.java | 4 - .../drive/periodicScan/PeriodicScanWorker.kt | 1 + .../e/drive/receivers/DebugCmdReceiver.java | 4 +- .../e/drive/services/ObserverService.java | 365 ------------------ .../e/drive/work/FirstStartWorker.java | 2 +- .../e/drive/work/FullScanWorker.java | 68 ---- .../e/drive/work/PeriodicWorker.java | 7 +- .../e/drive/work/WorkRequestFactory.java | 11 +- .../e/drive/services/AbstractServiceIT.java | 121 ------ 10 files changed, 13 insertions(+), 573 deletions(-) delete mode 100644 app/src/main/java/foundation/e/drive/services/ObserverService.java delete mode 100644 app/src/main/java/foundation/e/drive/work/FullScanWorker.java delete mode 100644 app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 177f5488..f8c0bfe3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -83,9 +83,6 @@ android:exported="true" android:label="@string/account_setting_metered_network" tools:ignore="ExportedContentProvider" /> - mSyncedFolders; //List of synced folder - private Account mAccount; - private HashMap syncRequests; //integer is SyncedFileState id; Parcelable is the operation - - private final SyncRequestCollector syncManager = SyncProxy.INSTANCE; - - private Handler handler; - private HandlerThread handlerThread; - // protected to avoid SyntheticAccessor - protected boolean forcedSync = false; - - /* Lifecycle Methods */ - @Override - public void onDestroy(){ - Timber.v("onDestroy()"); - if (handlerThread != null) handlerThread.quitSafely(); - mSyncedFolders = null; - super.onDestroy(); - } - - @Override - public void onCreate() { - super.onCreate(); - Timber.tag(ObserverService.class.getSimpleName()); - } - - @Override - - public int onStartCommand(@Nullable Intent intent, int flags, int startId) { - Timber.v("onStartCommand(%s)", startId); - - CommonUtils.setServiceUnCaughtExceptionHandler(this); - - final SharedPreferences prefs = this.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); - final String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); - final String accountType = getApplicationContext().getString(R.string.eelo_account_type); - this.mAccount = CommonUtils.getAccount(accountName, accountType, AccountManager.get(this)); - - forcedSync = intent != null && DebugCmdReceiver.ACTION_FORCE_SYNC.equals(intent.getAction()); - - this.syncRequests = new HashMap<>(); - - if (!checkStartCondition(prefs, forcedSync)) { - syncManager.startListeningFiles(getApplication()); - stopSelf(); - return START_NOT_STICKY; - } - - begin(); - return START_STICKY; - } - - /** - * This method check that all condition are met - * to start ObserverService: - * - a valid account as been registered - * - Synchronization of media and/or settings is enabled - * - Initialization task has been done properly - * - Service isn't already running - * - Check minimum delay since last call if not forced sync - * - Check that network is available depending of metered network allowed or not - * - * It also display log depending of the failure and send intent for initialization if this has - * not been done - * @return false if at least one condition is false - */ - // protected to avoid SyntheticAccessor - protected boolean checkStartCondition(@NonNull final SharedPreferences prefs, final boolean forcedSync) { - Timber.v("checkStartCondition()"); - - if (mAccount == null) { - Timber.d("No account registered"); - return false; - } - - if (!CommonUtils.isMediaSyncEnabled(mAccount) && !CommonUtils.isSettingsSyncEnabled(mAccount)) { - Timber.d("Synchronization has been disabled in account's settings"); - return false; - } - - if (!prefs.getBoolean(SETUP_COMPLETED, false)) { - Timber.d("setup hasn't been done"); - return false; - } - - // Check minimum delay since last call & not forced sync - /*@todo is it really usefull to check time beetween to start as it is started by WorkManager? - it matters only if we want to consider forced sync */ - final long lastSyncTime = prefs.getLong(AppConstants.KEY_LAST_SYNC_TIME, 0L); - final long currentTime = System.currentTimeMillis(); - if (!forcedSync && (currentTime - lastSyncTime ) < INTERSYNC_MINIMUM_DELAY ) { - Timber.d("Delay between now and last call is too short"); - return false; - } - - final boolean meteredNetworkAllowed = CommonUtils.isMeteredNetworkAllowed(mAccount); - //check for the case where intent has been launched by initializerService - if (!CommonUtils.haveNetworkConnection(this, meteredNetworkAllowed)) { - Timber.d("There is no allowed internet connexion."); - return false; - } - - - final boolean startAllowed = syncManager.onPeriodicScanStart(getApplication()); - Timber.d("starting periodic scan is allowed ? %s", startAllowed); - return startAllowed; - } - - /* Common methods */ - /** - * Start to bind this service to OperationManagerService or start scan if binding is already set. - * Method to factorise code that is called from different place - */ - // protected to avoid SyntheticAccessor - protected void begin(){ - clearCachedFile(); - deleteOldestCrashlogs(); - startScan(true); - } - - /** - * This method remove all the crash-logs file - * in external dir that are 10 days or more old. - */ - private void deleteOldestCrashlogs(){ - Timber.i("deleteOldestCrashLogs()"); - final File externalFilesDir = getExternalFilesDir(ServiceExceptionHandler.CRASH_LOG_FOLDER); - if (externalFilesDir == null) { - Timber.d("getExternalFilesDir() returned null. Preventing a NPE"); - return; - } - - final File[] fileToRemove = externalFilesDir.listFiles(new CrashlogsFileFilter()); - if (fileToRemove == null) { - Timber.d("getExternalFilesDir() returned null. Preventing a NPE"); - return; - } - - for (File file : fileToRemove) { - try { - file.delete(); - } catch (SecurityException exception) { - Timber.e(exception); - } - } - } - - /** - * Clear cached file unused: - */ - private void clearCachedFile(){ - Timber.i("clearCachedFile()"); - final File[] fileToRemove = this.getApplicationContext().getExternalCacheDir().listFiles(new OnlyFileFilter() ); - if (fileToRemove == null) return; - - for (File file : fileToRemove) { - try { - file.delete(); - } catch (SecurityException exception) { - Timber.e(exception); - } - } - } - - /** - * Start scanning job - * Load operation from DB - * @param remote if true looks for remote change. If false, look for local change. - **/ - - private void startScan(boolean remote) { - Timber.i("startScan(%s)", remote); - this.mSyncedFolders = loadSyncedFolders(); - - if (mSyncedFolders.isEmpty()) { - Timber.d("List of synced folders is empty"); - this.stopSelf(); - return; - } - - if (remote) { - final OwnCloudClient client = DavClientProvider.getInstance().getClientInstance(mAccount, getApplicationContext()); - if (client == null) { - Timber.d("OwnCloudClient is null"); - return; - } - - try { - handlerThread = new HandlerThread("syncService_onResponse"); - handlerThread.start(); - handler = new Handler(handlerThread.getLooper()); - final ListFileRemoteOperation loadOperation = new ListFileRemoteOperation(this.mSyncedFolders, this); - loadOperation.execute(client, this, handler); - } catch (IllegalArgumentException exception) { - Timber.e(exception); - } - } else { - scanLocalFiles(); - } - } - - /** - * Get list of synced folder depending of if media and setting sync are enabled. - * @return - */ - private List loadSyncedFolders(){ - final boolean mediaSyncEnabled = CommonUtils.isMediaSyncEnabled(mAccount); - final boolean settingsSyncedEnabled = CommonUtils.isSettingsSyncEnabled(mAccount); - - if (mediaSyncEnabled && settingsSyncedEnabled) { - return DbHelper.getAllSyncedFolders(this); - } else if (mediaSyncEnabled) { - return DbHelper.getSyncedFolderList(this, true); - } else if (settingsSyncedEnabled) { - return DbHelper.getSyncedFolderList(this, false); - } else { - return new ArrayList<>(); - } - } - - /** - * Handle end of remote Operation - * @param operation The RemoteOperation which ends and call this methods - * @param result The result of the remote Operation - */ - @Override - public void onRemoteOperationFinish(@Nullable RemoteOperation operation, @NonNull RemoteOperationResult result) { - Timber.d("onRemoteOperationFinish()"); - if (!(operation instanceof ListFileRemoteOperation)) return; - - if (!result.isSuccess()) { - Timber.d("ListRemoteFileOperation failed. Http code: %s", result.getHttpCode()); - } - - final List remoteFiles = ((RemoteOperationResult>)result).getResultData(); - - if (remoteFiles != null) { - final ListFileRemoteOperation listFileOperation = (ListFileRemoteOperation) operation; - final List syncedFoldersId = listFileOperation.getSyncedFoldersId(); - - final List syncedFileStates = DbHelper.getSyncedFileStatesByFolders(this, - syncedFoldersId); - - if (!remoteFiles.isEmpty() || !syncedFileStates.isEmpty()) { - final RemoteContentScanner scanner = new RemoteContentScanner(getApplicationContext(), mSyncedFolders); - syncRequests.putAll(scanner.scanContent(remoteFiles, syncedFileStates)); - } - } - - startScan(false); - - if (!syncRequests.isEmpty()) { - Timber.d("syncRequests contains %s", syncRequests.size()); - syncManager.queueSyncRequests(syncRequests.values(), getApplicationContext()); - syncManager.startSynchronization(getApplicationContext()); - } else { - Timber.i("There is no file to sync."); - getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) - .edit() - .putLong(AppConstants.KEY_LAST_SYNC_TIME, System.currentTimeMillis()) - .apply(); - syncManager.startListeningFiles(getApplication()); - } - - this.stopSelf(); - } - - /** - * Prepare the list of files and SyncedFileState for synchronisation - */ - private void scanLocalFiles(){ - Timber.i("scanLocalFiles()"); - - final LocalFileLister fileLister = new LocalFileLister(mSyncedFolders); - - final boolean isContentToScan = fileLister.listContentToScan(getApplicationContext()); - - if (!isContentToScan) { - return; - } - - final List fileList = fileLister.getContentToScan(); - final List folderIdList = fileLister.getSyncedFoldersId(); - - final List syncedFileStates = DbHelper.getSyncedFileStatesByFolders(this, - folderIdList); - - if (!syncedFileStates.isEmpty() || !fileList.isEmpty() ) { - final LocalContentScanner scanner= new LocalContentScanner(getApplicationContext(), mSyncedFolders); - syncRequests.putAll(scanner.scanContent(fileList, syncedFileStates)); - } - } - - @Nullable - @Override - public IBinder onBind(@Nullable Intent intent) { - throw new UnsupportedOperationException(); - } -} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java b/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java index 0ebce10f..859d8344 100644 --- a/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java +++ b/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java @@ -55,7 +55,7 @@ public class FirstStartWorker extends Worker { enqueuePeriodicFileScanWorkRequest(appContext); - getApplicationContext().startService(new Intent(getApplicationContext(), foundation.e.drive.services.ObserverService.class)); + //todo start PeriodicScanWorker return Result.success(); } catch (Exception exception) { diff --git a/app/src/main/java/foundation/e/drive/work/FullScanWorker.java b/app/src/main/java/foundation/e/drive/work/FullScanWorker.java deleted file mode 100644 index 156bcb73..00000000 --- a/app/src/main/java/foundation/e/drive/work/FullScanWorker.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright © ECORP SAS 2022. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/gpl.html - */ - -package foundation.e.drive.work; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.work.Worker; -import androidx.work.WorkerParameters; - -import foundation.e.drive.services.ObserverService; -import foundation.e.drive.utils.AppConstants; -import foundation.e.drive.utils.CommonUtils; -import timber.log.Timber; - -/** - * As a first step, this class must replace foundation.e.drive.jobs.ScannerJob - * in order to allow to use Jetpack Work API - * - * In further development it will be a part of Workers that will replace ObserverService - * I will update this header accordingly - * - * @author Vincent Bourgmayer - */ -public class FullScanWorker extends Worker { - public final static String UNIQUE_WORK_NAME = "FullScan"; - - public FullScanWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { - super(context, workerParams); - Timber.tag(FullScanWorker.class.getSimpleName()); - } - - @NonNull - @Override - public Result doWork() { - try { - Timber.v("doWork(): going to send intent to ObserverService"); - final SharedPreferences prefs = getApplicationContext().getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, - Context.MODE_PRIVATE); - final String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); - final String accountType = prefs.getString(AccountManager.KEY_ACCOUNT_TYPE, ""); - - final Account mAccount = CommonUtils.getAccount(accountName, accountType, AccountManager.get(this.getApplicationContext())); - - if (mAccount != null && CommonUtils.isSettingsSyncEnabled(mAccount) && CommonUtils.isMediaSyncEnabled(mAccount)) { - final Intent observerServiceIntent = new Intent(this.getApplicationContext(), ObserverService.class); - this.getApplicationContext().startService(observerServiceIntent); - } else { - Timber.d("Intent for ObserverService not send : account is null or \"settings sync\" & \"media sync\" settings are disabled"); - } - - return Result.success(); - } catch (Exception exception) { - Timber.e(exception); - return Result.retry(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java b/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java index 560ef9f9..af697f7d 100644 --- a/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java +++ b/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java @@ -9,7 +9,7 @@ package foundation.e.drive.work; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_LIST; -import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FULL_SCAN; +import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_PERIODIC_SCAN; import android.content.Context; @@ -23,6 +23,7 @@ import androidx.work.WorkerParameters; import java.util.ArrayList; import java.util.List; +import foundation.e.drive.periodicScan.PeriodicScanWorker; import timber.log.Timber; /** @@ -45,9 +46,9 @@ public class PeriodicWorker extends Worker { final List workRequestsLists = new ArrayList<>(); workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_APP_LIST, null)); - workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FULL_SCAN, null)); + workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_PERIODIC_SCAN, null)); - workManager.beginUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, workRequestsLists) + workManager.beginUniqueWork(PeriodicScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, workRequestsLists) .enqueue(); return Result.success(); diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 0bef2fd5..75152965 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -32,13 +32,14 @@ import java.security.InvalidParameterException; import java.util.concurrent.TimeUnit; import foundation.e.drive.models.SyncedFolder; +import foundation.e.drive.periodicScan.PeriodicScanWorker; import foundation.e.drive.utils.AppConstants; public class WorkRequestFactory { public enum WorkType { PERIODIC_USER_INFO, PERIODIC_SCAN, - ONE_TIME_FULL_SCAN, + ONE_TIME_PERIODIC_SCAN, ONE_TIME_APP_LIST, ONE_TIME_USER_INFO, CREATE_REMOTE_DIR, @@ -109,8 +110,8 @@ public class WorkRequestFactory { switch (type) { case ONE_TIME_APP_LIST: return createOneTimeAppListGenerationWorkRequest(); - case ONE_TIME_FULL_SCAN: - return createOneTimeFullScanWorkRequest(); + case ONE_TIME_PERIODIC_SCAN: + return createOneTimePeriodicScanWorkRequest(); case ONE_TIME_USER_INFO: return createOneTimeGetUserInfoWorkRequest(); case FIRST_START: @@ -143,10 +144,10 @@ public class WorkRequestFactory { * @return instance of OneTimeWorkRequest */ @NonNull - private static OneTimeWorkRequest createOneTimeFullScanWorkRequest() { + private static OneTimeWorkRequest createOneTimePeriodicScanWorkRequest() { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); - final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(FullScanWorker.class); + final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(PeriodicScanWorker.class); return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .setConstraints(constraints) diff --git a/app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java b/app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java deleted file mode 100644 index 99815760..00000000 --- a/app/src/test/java/foundation/e/drive/services/AbstractServiceIT.java +++ /dev/null @@ -1,121 +0,0 @@ -package foundation.e.drive.services; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.app.Service; -import android.app.job.JobScheduler; -import android.content.ContentResolver; -import android.content.Context; -import android.content.SharedPreferences; -import android.net.ConnectivityManager; -import android.os.Build; - -import org.junit.BeforeClass; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.android.controller.ServiceController; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowLog; - -import foundation.e.drive.TestUtils; -import foundation.e.drive.database.DbHelper; -import foundation.e.drive.utils.AppConstants; -import static foundation.e.drive.TestUtils.TEST_ACCOUNT_NAME; -import static foundation.e.drive.TestUtils.TEST_ACCOUNT_TYPE; -import static foundation.e.drive.utils.AppConstants.MEDIA_SYNC_PROVIDER_AUTHORITY; -import static foundation.e.drive.utils.AppConstants.SETTINGS_SYNC_PROVIDER_AUTHORITY; - -import com.nextcloud.common.NextcloudClient; - -@RunWith(RobolectricTestRunner.class) -@Config(sdk = Build.VERSION_CODES.O, manifest = Config.NONE) -public abstract class AbstractServiceIT { - - /** - * By making the below field static it is done once - * for all test class that extends this instead of - * one time by class. - */ - protected static Context context; - - protected T mService; - protected ServiceController mServiceController; - - protected AccountManager accountManager; - protected ContentResolver contentResolver; - protected SharedPreferences sharedPreferences; - protected ConnectivityManager connectivityManager; - protected JobScheduler jobScheduler; - protected DbHelper dbHelper; - protected NextcloudClient client; - protected int initial_folder_number=0; //number of folders to sync at initialization - protected long last_sync_time=0l; //Timestamp of the end of the last synchronisation - protected boolean init_done = true; //true if InitializerService did its job - protected boolean oms_running=false; //true if OperationManagerService is already running - - @BeforeClass - public static void beforeAll(){ - TestUtils.loadServerCredentials(); - ShadowLog.stream = System.out; //give access to log - } - - /** - * Create and register one validAccount - */ - protected void prepareValidAccount(){ - TestUtils.prepareValidAccount(accountManager); - } - - /** - * enable Media & settings sync - */ - protected void enableMediaAndSettingsSync(Account account){ //replace this by robolectric the contentResolver - contentResolver.setSyncAutomatically(account, MEDIA_SYNC_PROVIDER_AUTHORITY, true); - contentResolver.setSyncAutomatically(account, SETTINGS_SYNC_PROVIDER_AUTHORITY, true); - } - - /** - * disable Media & enable settings sync - */ - protected void disableMediaSync(Account account){ //replace this by robolectric the contentResolver - contentResolver.setSyncAutomatically(account, MEDIA_SYNC_PROVIDER_AUTHORITY, false); - contentResolver.setSyncAutomatically(account, SETTINGS_SYNC_PROVIDER_AUTHORITY, true); - } - - /** - * enable Media and disable settings sync - */ - protected void disableSettingsSync(Account account){ //replace this by robolectric the contentResolver - contentResolver.setSyncAutomatically(account, MEDIA_SYNC_PROVIDER_AUTHORITY, true); - contentResolver.setSyncAutomatically(account, SETTINGS_SYNC_PROVIDER_AUTHORITY, false); - } - - /** - * disable Media & settings sync - */ - protected void disableMediaAndSettingsSync(Account account){ //replace this by robolectric the contentResolver - contentResolver.setSyncAutomatically(account, MEDIA_SYNC_PROVIDER_AUTHORITY, false); - contentResolver.setSyncAutomatically(account, SETTINGS_SYNC_PROVIDER_AUTHORITY, false); - } - - /** - * Register sharedPreferences common to all services - * - OMS is working (bool) - * - Account name (String) - * - Account type (String) - * - initial folders number (int) - * - last sync time (long) - * - Initialization has been done (bool) - * - * Use default value of the instance field - * So update the field before to call this to store specific value - */ - protected void registerSharedPref(){ - sharedPreferences.edit().putBoolean( AppConstants.SETUP_COMPLETED, init_done) - .putString(AccountManager.KEY_ACCOUNT_NAME, TEST_ACCOUNT_NAME) - .putString(AccountManager.KEY_ACCOUNT_TYPE, TEST_ACCOUNT_TYPE) - .putInt(AppConstants.INITIAL_FOLDER_NUMBER, initial_folder_number) - .putLong(AppConstants.KEY_LAST_SYNC_TIME, last_sync_time) - .apply(); - } -} -- GitLab From ea4d2a777d24cc0e0e0297994f27c73b6f63657f Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 12:17:34 +0200 Subject: [PATCH 04/20] rename PeriodicScan to FullScan because it could also be run as unique immediate worker --- .../periodicScan/{PeriodicScanWorker.kt => FullScanWorker.kt} | 4 ++-- app/src/main/java/foundation/e/drive/work/PeriodicWorker.java | 4 ++-- .../main/java/foundation/e/drive/work/WorkRequestFactory.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename app/src/main/java/foundation/e/drive/periodicScan/{PeriodicScanWorker.kt => FullScanWorker.kt} (98%) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt similarity index 98% rename from app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt rename to app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index 4dcb69ad..5f4f9c56 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -32,7 +32,7 @@ import foundation.e.drive.utils.DavClientProvider import timber.log.Timber import java.util.ArrayList -class PeriodicScanWorker(private val context: Context, private val workerParams: WorkerParameters) : +class FullScanWorker(private val context: Context, private val workerParams: WorkerParameters) : Worker(context, workerParams) { @@ -41,7 +41,7 @@ class PeriodicScanWorker(private val context: Context, private val workerParams: companion object { private const val SYNC_MINIMUM_DELAY = 900000 // min delay between two run in ms. const val ACTION_FORCED_SYNC_KEY = "forced_sync" - const val UNIQUE_WORK_NAME = "periodicScan" + const val UNIQUE_WORK_NAME = "fullScan" } override fun doWork(): Result { diff --git a/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java b/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java index af697f7d..bc9e4a9e 100644 --- a/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java +++ b/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java @@ -23,7 +23,7 @@ import androidx.work.WorkerParameters; import java.util.ArrayList; import java.util.List; -import foundation.e.drive.periodicScan.PeriodicScanWorker; +import foundation.e.drive.periodicScan.FullScanWorker; import timber.log.Timber; /** @@ -48,7 +48,7 @@ public class PeriodicWorker extends Worker { workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_APP_LIST, null)); workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_PERIODIC_SCAN, null)); - workManager.beginUniqueWork(PeriodicScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, workRequestsLists) + workManager.beginUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, workRequestsLists) .enqueue(); return Result.success(); diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 75152965..125d520f 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -32,7 +32,7 @@ import java.security.InvalidParameterException; import java.util.concurrent.TimeUnit; import foundation.e.drive.models.SyncedFolder; -import foundation.e.drive.periodicScan.PeriodicScanWorker; +import foundation.e.drive.periodicScan.FullScanWorker; import foundation.e.drive.utils.AppConstants; public class WorkRequestFactory { @@ -147,7 +147,7 @@ public class WorkRequestFactory { private static OneTimeWorkRequest createOneTimePeriodicScanWorkRequest() { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); - final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(PeriodicScanWorker.class); + final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(FullScanWorker.class); return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .setConstraints(constraints) -- GitLab From 1344a76dffcc51054c617c41c80cff4538cad291 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 15:29:50 +0200 Subject: [PATCH 05/20] Rename FirstStartWorker into FinishSetupWorker --- .../account/receivers/AccountAddedReceiver.kt | 1 - ...tartWorker.java => FinishSetupWorker.java} | 31 +++++++++---------- .../e/drive/work/WorkRequestFactory.java | 2 +- 3 files changed, 15 insertions(+), 19 deletions(-) rename app/src/main/java/foundation/e/drive/work/{FirstStartWorker.java => FinishSetupWorker.java} (75%) diff --git a/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt b/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt index f14a3e06..5a9908ff 100644 --- a/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt +++ b/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt @@ -105,7 +105,6 @@ class AccountAddedReceiver() : BroadcastReceiver() { val rootFolderSetupWorkers = generateRootFolderSetupWorkers(context) ?: return false val getUserInfoRequest = getOneTimeWorkRequest(WorkType.ONE_TIME_USER_INFO, null) val firstStartRequest = getOneTimeWorkRequest(WorkType.FIRST_START, null) - val workManager = WorkManager.getInstance(context) workManager.beginWith(getUserInfoRequest) diff --git a/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java b/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java similarity index 75% rename from app/src/main/java/foundation/e/drive/work/FirstStartWorker.java rename to app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java index 859d8344..d5d7a6d4 100644 --- a/app/src/main/java/foundation/e/drive/work/FirstStartWorker.java +++ b/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java @@ -13,7 +13,6 @@ import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_L import static foundation.e.drive.work.WorkRequestFactory.WorkType.PERIODIC_SCAN; import android.content.Context; -import android.content.Intent; import androidx.annotation.NonNull; import androidx.work.ExistingPeriodicWorkPolicy; @@ -21,42 +20,31 @@ import androidx.work.WorkManager; import androidx.work.Worker; import androidx.work.WorkerParameters; -import foundation.e.drive.EdriveApplication; import foundation.e.drive.utils.AppConstants; import timber.log.Timber; /** - * This class start eDrive work after initialization. + * This class perform last task of setup * It contains job to start FileObserver, periodic fullScan and Synchronization service * for the first time * @author Vincent Bourgmayer */ -public class FirstStartWorker extends Worker { - public FirstStartWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { +public class FinishSetupWorker extends Worker { + public FinishSetupWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); - Timber.tag(FirstStartWorker.class.getSimpleName()); } @NonNull @Override public Result doWork() { - Timber.v("FirstStartWorker.doWork()"); + Timber.v("FinishSetupWorker.doWork()"); try { final Context appContext = getApplicationContext(); - enqueueAppListGenerationWorkRequest(appContext); - - appContext.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, - Context.MODE_PRIVATE) - .edit() - .putBoolean(AppConstants.SETUP_COMPLETED, true) - .putInt(INITIAL_FOLDER_NUMBER, 9) - .apply(); - enqueuePeriodicFileScanWorkRequest(appContext); //todo start PeriodicScanWorker - + updateSharedPreferences(appContext); return Result.success(); } catch (Exception exception) { Timber.e(exception); @@ -64,6 +52,15 @@ public class FirstStartWorker extends Worker { return Result.retry(); } + private void updateSharedPreferences(Context appContext) { + appContext.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, + Context.MODE_PRIVATE) + .edit() + .putBoolean(AppConstants.SETUP_COMPLETED, true) + .putInt(INITIAL_FOLDER_NUMBER, 9) + .apply(); + } + private void enqueueAppListGenerationWorkRequest(@NonNull final Context context) { final WorkManager workManager = WorkManager.getInstance(context); workManager.enqueue(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_APP_LIST, null)); diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 125d520f..6f609ef1 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -200,7 +200,7 @@ public class WorkRequestFactory { */ @NonNull private static OneTimeWorkRequest createOneTimeFirstStartWorkRequest() { - return new OneTimeWorkRequest.Builder(FirstStartWorker.class) + return new OneTimeWorkRequest.Builder(FinishSetupWorker.class) .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .addTag(AppConstants.WORK_GENERIC_TAG) .addTag(AppConstants.WORK_INITIALIZATION_TAG) -- GitLab From fc088ce485c986448f2427a4cc6c4a8b599394de Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 15:33:30 +0200 Subject: [PATCH 06/20] move AppListWorker & ListFileRemoteOperation into periodicScan package --- .../java/foundation/e/drive/periodicScan/FullScanWorker.kt | 7 +++++-- .../e/drive/{work => periodicScan}/ListAppsWorker.java | 2 +- .../ListFileRemoteOperation.java | 2 +- .../java/foundation/e/drive/work/WorkRequestFactory.java | 1 + 4 files changed, 8 insertions(+), 4 deletions(-) rename app/src/main/java/foundation/e/drive/{work => periodicScan}/ListAppsWorker.java (99%) rename app/src/main/java/foundation/e/drive/{operations => periodicScan}/ListFileRemoteOperation.java (98%) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index 5f4f9c56..f44c6864 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -20,7 +20,6 @@ import foundation.e.drive.R import foundation.e.drive.database.DbHelper import foundation.e.drive.models.SyncRequest import foundation.e.drive.models.SyncedFolder -import foundation.e.drive.operations.ListFileRemoteOperation import foundation.e.drive.periodicScan.contentScanner.LocalContentScanner import foundation.e.drive.periodicScan.contentScanner.LocalFileLister import foundation.e.drive.periodicScan.contentScanner.RemoteContentScanner @@ -160,7 +159,11 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor */ private fun scanRemoteFiles(account: Account, syncedFolders: List): HashMap { val ocClient = DavClientProvider.getInstance().getClientInstance(account, context)?: return HashMap() - val listRemoteFilesOperation = ListFileRemoteOperation(syncedFolders, context) + val listRemoteFilesOperation = + ListFileRemoteOperation( + syncedFolders, + context + ) try { @Suppress("DEPRECATION") diff --git a/app/src/main/java/foundation/e/drive/work/ListAppsWorker.java b/app/src/main/java/foundation/e/drive/periodicScan/ListAppsWorker.java similarity index 99% rename from app/src/main/java/foundation/e/drive/work/ListAppsWorker.java rename to app/src/main/java/foundation/e/drive/periodicScan/ListAppsWorker.java index 1309f6ee..6c6b9062 100644 --- a/app/src/main/java/foundation/e/drive/work/ListAppsWorker.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/ListAppsWorker.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.work; +package foundation.e.drive.periodicScan; import static com.owncloud.android.lib.resources.files.FileUtils.PATH_SEPARATOR; diff --git a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java similarity index 98% rename from app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java rename to app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java index 46dadfe4..db14484a 100644 --- a/app/src/main/java/foundation/e/drive/operations/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java @@ -7,7 +7,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.operations; +package foundation.e.drive.periodicScan; import android.content.Context; diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 6f609ef1..8bfc799c 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -33,6 +33,7 @@ import java.util.concurrent.TimeUnit; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.periodicScan.FullScanWorker; +import foundation.e.drive.periodicScan.ListAppsWorker; import foundation.e.drive.utils.AppConstants; public class WorkRequestFactory { -- GitLab From b9d9fc517edc4014967ba96020be30b1a2601652 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 16:07:13 +0200 Subject: [PATCH 07/20] rename some worker class & var for better consistency --- .../account/receivers/AccountAddedReceiver.kt | 10 ++--- .../PeriodicScanWorker.java} | 14 +++---- .../e/drive/work/FinishSetupWorker.java | 3 +- .../e/drive/work/WorkRequestFactory.java | 40 +++++++++---------- 4 files changed, 34 insertions(+), 33 deletions(-) rename app/src/main/java/foundation/e/drive/{work/PeriodicWorker.java => periodicScan/PeriodicScanWorker.java} (82%) diff --git a/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt b/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt index 5a9908ff..4e0b9248 100644 --- a/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt +++ b/app/src/main/java/foundation/e/drive/account/receivers/AccountAddedReceiver.kt @@ -104,12 +104,12 @@ class AccountAddedReceiver() : BroadcastReceiver() { private fun registerSetupWorkers(context: Context): Boolean { val rootFolderSetupWorkers = generateRootFolderSetupWorkers(context) ?: return false val getUserInfoRequest = getOneTimeWorkRequest(WorkType.ONE_TIME_USER_INFO, null) - val firstStartRequest = getOneTimeWorkRequest(WorkType.FIRST_START, null) + val finishSetupRequest = getOneTimeWorkRequest(WorkType.ONE_TIME_FINISH_SETUP, null) val workManager = WorkManager.getInstance(context) workManager.beginWith(getUserInfoRequest) .then(rootFolderSetupWorkers) - .then(firstStartRequest) + .then(finishSetupRequest) .enqueue() return true } @@ -124,11 +124,11 @@ class AccountAddedReceiver() : BroadcastReceiver() { val workRequests: MutableList = ArrayList() for (folder in rootSyncedFolderList) { - val createRemoteFolderWorkRequest = getOneTimeWorkRequest( - WorkType.CREATE_REMOTE_DIR, + val rootFolderSetupWorkRequest = getOneTimeWorkRequest( + WorkType.ONE_TIME_ROOT_FOLDER_SETUP, folder ) - workRequests.add(createRemoteFolderWorkRequest) + workRequests.add(rootFolderSetupWorkRequest) } return workRequests } diff --git a/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java b/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.java similarity index 82% rename from app/src/main/java/foundation/e/drive/work/PeriodicWorker.java rename to app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.java index bc9e4a9e..ffaf89c6 100644 --- a/app/src/main/java/foundation/e/drive/work/PeriodicWorker.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/PeriodicScanWorker.java @@ -6,10 +6,10 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.work; +package foundation.e.drive.periodicScan; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_LIST; -import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_PERIODIC_SCAN; +import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FULL_SCAN; import android.content.Context; @@ -23,7 +23,7 @@ import androidx.work.WorkerParameters; import java.util.ArrayList; import java.util.List; -import foundation.e.drive.periodicScan.FullScanWorker; +import foundation.e.drive.work.WorkRequestFactory; import timber.log.Timber; /** @@ -32,9 +32,9 @@ import timber.log.Timber; * at the moment * @author vincent Bourgmayer */ -public class PeriodicWorker extends Worker { - public final static String UNIQUE_WORK_NAME = "periodicWork"; - public PeriodicWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { +public class PeriodicScanWorker extends Worker { + public final static String UNIQUE_WORK_NAME = "periodicScanWork"; + public PeriodicScanWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); } @@ -46,7 +46,7 @@ public class PeriodicWorker extends Worker { final List workRequestsLists = new ArrayList<>(); workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_APP_LIST, null)); - workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_PERIODIC_SCAN, null)); + workRequestsLists.add(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FULL_SCAN, null)); workManager.beginUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, workRequestsLists) .enqueue(); diff --git a/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java b/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java index d5d7a6d4..c0445b3e 100644 --- a/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java @@ -20,6 +20,7 @@ import androidx.work.WorkManager; import androidx.work.Worker; import androidx.work.WorkerParameters; +import foundation.e.drive.periodicScan.PeriodicScanWorker; import foundation.e.drive.utils.AppConstants; import timber.log.Timber; @@ -69,7 +70,7 @@ public class FinishSetupWorker extends Worker { private void enqueuePeriodicFileScanWorkRequest(@NonNull final Context context) { final WorkManager workManager = WorkManager.getInstance(context); - workManager.enqueueUniquePeriodicWork(PeriodicWorker.UNIQUE_WORK_NAME, + workManager.enqueueUniquePeriodicWork(PeriodicScanWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.KEEP, WorkRequestFactory.getPeriodicWorkRequest(PERIODIC_SCAN)); } diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 8bfc799c..63c7e0bd 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -34,17 +34,18 @@ import java.util.concurrent.TimeUnit; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.periodicScan.FullScanWorker; import foundation.e.drive.periodicScan.ListAppsWorker; +import foundation.e.drive.periodicScan.PeriodicScanWorker; import foundation.e.drive.utils.AppConstants; public class WorkRequestFactory { public enum WorkType { PERIODIC_USER_INFO, PERIODIC_SCAN, - ONE_TIME_PERIODIC_SCAN, + ONE_TIME_FULL_SCAN, ONE_TIME_APP_LIST, ONE_TIME_USER_INFO, - CREATE_REMOTE_DIR, - FIRST_START + ONE_TIME_ROOT_FOLDER_SETUP, + ONE_TIME_FINISH_SETUP } /** @@ -66,7 +67,7 @@ public class WorkRequestFactory { } /** - * Create a PeridocWorkRequest instance for + * Create a PeriodicWorkRequest instance for * a Full scan with constraints on network (should * be unmetered) and battery (shouldn't be low) * @return instance of PeriodicWorkRequest @@ -75,7 +76,7 @@ public class WorkRequestFactory { private static PeriodicWorkRequest createPeriodicScanWorkRequest() { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); - return new PeriodicWorkRequest.Builder(PeriodicWorker.class, + return new PeriodicWorkRequest.Builder(PeriodicScanWorker.class, 26, TimeUnit.MINUTES, 5, TimeUnit.MINUTES) .setConstraints(constraints) .addTag(AppConstants.WORK_GENERIC_TAG) @@ -110,16 +111,16 @@ public class WorkRequestFactory { public static OneTimeWorkRequest getOneTimeWorkRequest(@NonNull WorkType type, @Nullable SyncedFolder syncedFolder) { switch (type) { case ONE_TIME_APP_LIST: - return createOneTimeAppListGenerationWorkRequest(); - case ONE_TIME_PERIODIC_SCAN: - return createOneTimePeriodicScanWorkRequest(); + return createAppListGenerationWorkRequest(); + case ONE_TIME_FULL_SCAN: + return createFullScanWorkRequest(); case ONE_TIME_USER_INFO: - return createOneTimeGetUserInfoWorkRequest(); - case FIRST_START: - return createOneTimeFirstStartWorkRequest(); - case CREATE_REMOTE_DIR: + return createGetUserInfoWorkRequest(); + case ONE_TIME_FINISH_SETUP: + return createFinishSetupWorkRequest(); + case ONE_TIME_ROOT_FOLDER_SETUP: if (syncedFolder == null) throw new NullPointerException("Synced folder is null"); - return createOneTimeCreateRemoteFolderWorkRequest(syncedFolder); + return createRootFolderSetupWorkRequest(syncedFolder); default: throw new InvalidParameterException("Unsupported Work Type: " + type); } @@ -130,7 +131,7 @@ public class WorkRequestFactory { * @return the workRequest */ @NonNull - private static OneTimeWorkRequest createOneTimeAppListGenerationWorkRequest() { + private static OneTimeWorkRequest createAppListGenerationWorkRequest() { final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(ListAppsWorker.class); return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) @@ -145,7 +146,7 @@ public class WorkRequestFactory { * @return instance of OneTimeWorkRequest */ @NonNull - private static OneTimeWorkRequest createOneTimePeriodicScanWorkRequest() { + private static OneTimeWorkRequest createFullScanWorkRequest() { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(FullScanWorker.class); @@ -162,7 +163,7 @@ public class WorkRequestFactory { * @return instance of OneTimeWorkRequest */ @NonNull - private static OneTimeWorkRequest createOneTimeGetUserInfoWorkRequest() { + private static OneTimeWorkRequest createGetUserInfoWorkRequest() { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(AccountUserInfoWorker.class); @@ -181,7 +182,7 @@ public class WorkRequestFactory { * @return Instance OneTimeWorkRequest */ @NonNull - private static OneTimeWorkRequest createOneTimeCreateRemoteFolderWorkRequest(@NonNull SyncedFolder syncedFolder) { + private static OneTimeWorkRequest createRootFolderSetupWorkRequest(@NonNull SyncedFolder syncedFolder) { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); return new OneTimeWorkRequest.Builder( @@ -195,12 +196,11 @@ public class WorkRequestFactory { } /** - * Create a OneTime WorkRequest which start eDrive - * after initialization + * Create a OneTime WorkRequest which finish setup process * @return Instance of OneTimeWorkRequest */ @NonNull - private static OneTimeWorkRequest createOneTimeFirstStartWorkRequest() { + private static OneTimeWorkRequest createFinishSetupWorkRequest() { return new OneTimeWorkRequest.Builder(FinishSetupWorker.class) .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .addTag(AppConstants.WORK_GENERIC_TAG) -- GitLab From b0f1c4902d8c8c8ca9508a3d524a65da978641f1 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 16:15:56 +0200 Subject: [PATCH 08/20] add missing try catch in FullScanWorker --- .../e/drive/periodicScan/FullScanWorker.kt | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index f44c6864..d74aa8f4 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -29,7 +29,6 @@ import foundation.e.drive.utils.AppConstants import foundation.e.drive.utils.CommonUtils import foundation.e.drive.utils.DavClientProvider import timber.log.Timber -import java.util.ArrayList class FullScanWorker(private val context: Context, private val workerParams: WorkerParameters) : Worker(context, workerParams) @@ -44,37 +43,47 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor } override fun doWork(): Result { - val requestCollector: SyncRequestCollector = SyncProxy + try { + val requestCollector: SyncRequestCollector = SyncProxy - val prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) - val account = loadAccount(prefs) + val prefs = context.getSharedPreferences( + AppConstants.SHARED_PREFERENCE_NAME, + Context.MODE_PRIVATE + ) + val account = loadAccount(prefs) - val startAllowed = checkStartConditions(account, prefs, requestCollector) - if (!startAllowed) { - Timber.d("Start Periodic Scan is not allowed") - requestCollector.startListeningFiles(applicationContext as Application) - return Result.failure() - } + val startAllowed = checkStartConditions(account, prefs, requestCollector) + if (!startAllowed) { + Timber.d("Start Periodic Scan is not allowed") + requestCollector.startListeningFiles(applicationContext as Application) + return Result.failure() + } - val syncFolders = loadSyncedFolders(account!!) - if (syncFolders.isEmpty()) { - requestCollector.startListeningFiles(applicationContext as Application) - return Result.success() - } + val syncFolders = loadSyncedFolders(account!!) + if (syncFolders.isEmpty()) { + requestCollector.startListeningFiles(applicationContext as Application) + return Result.success() + } - val remoteSyncRequest = scanRemoteFiles(account, syncFolders.toMutableList()) - syncRequests.putAll(remoteSyncRequest) + val remoteSyncRequests = scanRemoteFiles(account, syncFolders.toMutableList()) + syncRequests.putAll(remoteSyncRequests) - val localSyncRequest = scanLocalFiles(syncFolders.toMutableList()) - syncRequests.putAll(localSyncRequest) + val localSyncRequests = scanLocalFiles(syncFolders.toMutableList()) + syncRequests.putAll(localSyncRequests) - if (syncRequests.isEmpty()) { - requestCollector.startListeningFiles(applicationContext as Application) + if (syncRequests.isEmpty()) { + requestCollector.startListeningFiles(applicationContext as Application) + return Result.success() + } + + requestCollector.queueSyncRequests(syncRequests.values, context) + requestCollector.startSynchronization(applicationContext) return Result.success() + + } catch (exception: Exception) { + Timber.e(exception) + return Result.failure() } - requestCollector.queueSyncRequests(syncRequests.values, context) - requestCollector.startSynchronization(applicationContext) - return Result.success() } /** @@ -194,7 +203,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor val localFileLister = LocalFileLister(syncedFolders) val isContentToScan = localFileLister.listContentToScan(context) - if(!isContentToScan) { + if (!isContentToScan) { return HashMap() } @@ -208,6 +217,4 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor } return HashMap() } - - } \ No newline at end of file -- GitLab From 5b9a270fe9973a3ed7336ab0bc1763d7dda7eba7 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 16:21:16 +0200 Subject: [PATCH 09/20] move class related to setup or account into account package --- .../AccountUserInfoWorker.java | 3 +-- .../GetAliasOperation.java | 2 +- .../setup}/FinishSetupWorker.java | 3 ++- .../setup}/RootFolderSetupWorker.java | 2 +- .../foundation/e/drive/utils/CommonUtils.java | 6 +---- .../e/drive/work/WorkRequestFactory.java | 23 +++++++++++-------- 6 files changed, 19 insertions(+), 20 deletions(-) rename app/src/main/java/foundation/e/drive/{work => account}/AccountUserInfoWorker.java (99%) rename app/src/main/java/foundation/e/drive/{operations => account}/GetAliasOperation.java (98%) rename app/src/main/java/foundation/e/drive/{work => account/setup}/FinishSetupWorker.java (96%) rename app/src/main/java/foundation/e/drive/{work => account/setup}/RootFolderSetupWorker.java (99%) diff --git a/app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java b/app/src/main/java/foundation/e/drive/account/AccountUserInfoWorker.java similarity index 99% rename from app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java rename to app/src/main/java/foundation/e/drive/account/AccountUserInfoWorker.java index 39b308c1..8d4d0aa6 100644 --- a/app/src/main/java/foundation/e/drive/work/AccountUserInfoWorker.java +++ b/app/src/main/java/foundation/e/drive/account/AccountUserInfoWorker.java @@ -5,7 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.work; +package foundation.e.drive.account; import static foundation.e.drive.utils.AppConstants.ACCOUNT_DATA_ALIAS_KEY; import static foundation.e.drive.utils.AppConstants.ACCOUNT_DATA_EMAIL; @@ -40,7 +40,6 @@ import java.util.ArrayList; import foundation.e.drive.R; import foundation.e.drive.activity.AccountsActivity; -import foundation.e.drive.operations.GetAliasOperation; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; diff --git a/app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java b/app/src/main/java/foundation/e/drive/account/GetAliasOperation.java similarity index 98% rename from app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java rename to app/src/main/java/foundation/e/drive/account/GetAliasOperation.java index e1de65d5..2f7d26d5 100644 --- a/app/src/main/java/foundation/e/drive/operations/GetAliasOperation.java +++ b/app/src/main/java/foundation/e/drive/account/GetAliasOperation.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.operations; +package foundation.e.drive.account; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java similarity index 96% rename from app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java rename to app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java index c0445b3e..579189de 100644 --- a/app/src/main/java/foundation/e/drive/work/FinishSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.work; +package foundation.e.drive.account.setup; import static foundation.e.drive.utils.AppConstants.INITIAL_FOLDER_NUMBER; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_LIST; @@ -22,6 +22,7 @@ import androidx.work.WorkerParameters; import foundation.e.drive.periodicScan.PeriodicScanWorker; import foundation.e.drive.utils.AppConstants; +import foundation.e.drive.work.WorkRequestFactory; import timber.log.Timber; /** diff --git a/app/src/main/java/foundation/e/drive/work/RootFolderSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java similarity index 99% rename from app/src/main/java/foundation/e/drive/work/RootFolderSetupWorker.java rename to app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java index 8ff54f22..6488eeb5 100644 --- a/app/src/main/java/foundation/e/drive/work/RootFolderSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java @@ -6,7 +6,7 @@ * http://www.gnu.org/licenses/gpl.html */ -package foundation.e.drive.work; +package foundation.e.drive.account.setup; import android.accounts.Account; import android.accounts.AccountManager; diff --git a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java index 1d6ec907..a9fd0c00 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -29,12 +29,9 @@ import java.lang.reflect.Method; import java.text.CharacterIterator; import java.text.StringCharacterIterator; import java.util.Locale; -import java.util.ArrayList; -import java.util.List; import foundation.e.drive.R; -import foundation.e.drive.models.SyncedFolder; -import foundation.e.drive.work.AccountUserInfoWorker; +import foundation.e.drive.account.AccountUserInfoWorker; import foundation.e.drive.work.WorkRequestFactory; import timber.log.Timber; @@ -45,7 +42,6 @@ import static foundation.e.drive.utils.AppConstants.SETTINGS_SYNC_PROVIDER_AUTHO import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.work.ExistingPeriodicWorkPolicy; -import androidx.work.OneTimeWorkRequest; import androidx.work.PeriodicWorkRequest; import androidx.work.WorkManager; diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 63c7e0bd..fa32811e 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -8,16 +8,16 @@ package foundation.e.drive.work; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_ENABLE; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_ID; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_LAST_ETAG; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_LAST_MODIFIED; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_LIBELLE; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_LOCAL_PATH; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_MEDIATYPE; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_REMOTE_PATH; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_SCAN_LOCAL; -import static foundation.e.drive.work.RootFolderSetupWorker.DATA_KEY_SCAN_REMOTE; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_ENABLE; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_ID; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_LAST_ETAG; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_LAST_MODIFIED; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_LIBELLE; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_LOCAL_PATH; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_MEDIATYPE; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_REMOTE_PATH; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_SCAN_LOCAL; +import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_SCAN_REMOTE; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -31,6 +31,9 @@ import androidx.work.PeriodicWorkRequest; import java.security.InvalidParameterException; import java.util.concurrent.TimeUnit; +import foundation.e.drive.account.AccountUserInfoWorker; +import foundation.e.drive.account.setup.FinishSetupWorker; +import foundation.e.drive.account.setup.RootFolderSetupWorker; import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.periodicScan.FullScanWorker; import foundation.e.drive.periodicScan.ListAppsWorker; -- GitLab From 605378bda830be3d1eeeab27bbd22ee3f07dd1b6 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 16:51:22 +0200 Subject: [PATCH 10/20] trigger FullScanWorker once setup is finished --- .../account/setup/FinishSetupWorker.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java index 579189de..ba1b6bc7 100644 --- a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java @@ -10,16 +10,19 @@ package foundation.e.drive.account.setup; import static foundation.e.drive.utils.AppConstants.INITIAL_FOLDER_NUMBER; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_LIST; +import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FULL_SCAN; import static foundation.e.drive.work.WorkRequestFactory.WorkType.PERIODIC_SCAN; import android.content.Context; import androidx.annotation.NonNull; import androidx.work.ExistingPeriodicWorkPolicy; +import androidx.work.ExistingWorkPolicy; import androidx.work.WorkManager; import androidx.work.Worker; import androidx.work.WorkerParameters; +import foundation.e.drive.periodicScan.FullScanWorker; import foundation.e.drive.periodicScan.PeriodicScanWorker; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.work.WorkRequestFactory; @@ -42,12 +45,11 @@ public class FinishSetupWorker extends Worker { Timber.v("FinishSetupWorker.doWork()"); try { final Context appContext = getApplicationContext(); - enqueueAppListGenerationWorkRequest(appContext); - enqueuePeriodicFileScanWorkRequest(appContext); - - //todo start PeriodicScanWorker + enqueueWorkers(appContext); updateSharedPreferences(appContext); + return Result.success(); + } catch (Exception exception) { Timber.e(exception); } @@ -63,14 +65,24 @@ public class FinishSetupWorker extends Worker { .apply(); } - private void enqueueAppListGenerationWorkRequest(@NonNull final Context context) { - final WorkManager workManager = WorkManager.getInstance(context); - workManager.enqueue(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_APP_LIST, null)); + private void enqueueWorkers(@NonNull final Context appContext) { + final WorkManager workManager = WorkManager.getInstance(appContext); + enqueueAppListGenerationWorker(workManager); + enqueueFullScanWorker(workManager); + enqueuePeriodicFileScanWorker(workManager); } - private void enqueuePeriodicFileScanWorkRequest(@NonNull final Context context) { - final WorkManager workManager = WorkManager.getInstance(context); + private void enqueueFullScanWorker(@NonNull final WorkManager workManager) { + workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingWorkPolicy.KEEP, + WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FULL_SCAN, null)); + } + + private void enqueueAppListGenerationWorker(@NonNull final WorkManager workManager) { + workManager.enqueue(WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_APP_LIST, null)); + } + private void enqueuePeriodicFileScanWorker(@NonNull final WorkManager workManager) { workManager.enqueueUniquePeriodicWork(PeriodicScanWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.KEEP, WorkRequestFactory.getPeriodicWorkRequest(PERIODIC_SCAN)); -- GitLab From 237f3149d32198fbb288882c347d48d92ba3232f Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 17:10:34 +0200 Subject: [PATCH 11/20] allow to start expedited work for FullScanWorker after finishSetup & from DebugCmdReceiver --- .../drive/account/setup/FinishSetupWorker.java | 3 ++- .../e/drive/receivers/DebugCmdReceiver.java | 13 ++++++++++++- .../e/drive/work/WorkRequestFactory.java | 18 ++++++++++++++++-- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java index ba1b6bc7..6a846f7f 100644 --- a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java @@ -10,6 +10,7 @@ package foundation.e.drive.account.setup; import static foundation.e.drive.utils.AppConstants.INITIAL_FOLDER_NUMBER; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_LIST; +import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FORCED_FULL_SCAN; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FULL_SCAN; import static foundation.e.drive.work.WorkRequestFactory.WorkType.PERIODIC_SCAN; @@ -75,7 +76,7 @@ public class FinishSetupWorker extends Worker { private void enqueueFullScanWorker(@NonNull final WorkManager workManager) { workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, - WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FULL_SCAN, null)); + WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FORCED_FULL_SCAN, null)); } private void enqueueAppListGenerationWorker(@NonNull final WorkManager workManager) { diff --git a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java index 3c331fd2..b4b6cf29 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -7,14 +7,21 @@ */ package foundation.e.drive.receivers; +import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FORCED_FULL_SCAN; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import androidx.annotation.NonNull; +import androidx.work.ExistingWorkPolicy; +import androidx.work.OneTimeWorkRequest; +import androidx.work.WorkManager; import foundation.e.drive.database.DbHelper; +import foundation.e.drive.periodicScan.FullScanWorker; import foundation.e.drive.utils.ReleaseTree; +import foundation.e.drive.work.WorkRequestFactory; import timber.log.Timber; /** @@ -33,7 +40,11 @@ public class DebugCmdReceiver extends BroadcastReceiver { switch (intent.getAction()) { case ACTION_FORCE_SYNC: Timber.d("Force Sync intent received"); - // todo run PeriodicScanWorker as immediat runner + final WorkManager workManager = WorkManager.getInstance(context); + final OneTimeWorkRequest fullScanWorkRequest = WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FORCED_FULL_SCAN, null); + workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingWorkPolicy.KEEP, + fullScanWorkRequest); break; case ACTION_DUMP_DATABASE: Timber.d("Dump database intent received"); diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index fa32811e..bb8cdf60 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -26,7 +26,9 @@ import androidx.work.Constraints; import androidx.work.Data; import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; +import androidx.work.OutOfQuotaPolicy; import androidx.work.PeriodicWorkRequest; +import androidx.work.WorkerParameters; import java.security.InvalidParameterException; import java.util.concurrent.TimeUnit; @@ -45,6 +47,7 @@ public class WorkRequestFactory { PERIODIC_USER_INFO, PERIODIC_SCAN, ONE_TIME_FULL_SCAN, + ONE_TIME_FORCED_FULL_SCAN, ONE_TIME_APP_LIST, ONE_TIME_USER_INFO, ONE_TIME_ROOT_FOLDER_SETUP, @@ -116,7 +119,9 @@ public class WorkRequestFactory { case ONE_TIME_APP_LIST: return createAppListGenerationWorkRequest(); case ONE_TIME_FULL_SCAN: - return createFullScanWorkRequest(); + return createFullScanWorkRequest(false); + case ONE_TIME_FORCED_FULL_SCAN: + return createFullScanWorkRequest(true); case ONE_TIME_USER_INFO: return createGetUserInfoWorkRequest(); case ONE_TIME_FINISH_SETUP: @@ -149,13 +154,22 @@ public class WorkRequestFactory { * @return instance of OneTimeWorkRequest */ @NonNull - private static OneTimeWorkRequest createFullScanWorkRequest() { + private static OneTimeWorkRequest createFullScanWorkRequest(boolean forced) { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(FullScanWorker.class); + final Data data = new Data.Builder() + .putBoolean(FullScanWorker.ACTION_FORCED_SYNC_KEY, forced) + .build(); + + if (forced) { + builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST); + } + return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .setConstraints(constraints) + .setInputData(data) .addTag(AppConstants.WORK_GENERIC_TAG) .build(); } -- GitLab From b929bd0cdfeaa6d5e9cf3409ca4c40a8320ca1fd Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 26 Oct 2023 18:14:14 +0200 Subject: [PATCH 12/20] fix error in FullScanWorker --- .../foundation/e/drive/periodicScan/FullScanWorker.kt | 10 +++++++--- .../foundation/e/drive/work/WorkRequestFactory.java | 4 ---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index d74aa8f4..59bb5759 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -68,14 +68,18 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor val remoteSyncRequests = scanRemoteFiles(account, syncFolders.toMutableList()) syncRequests.putAll(remoteSyncRequests) + Timber.d("${remoteSyncRequests.size} request collected from cloud") + val localSyncRequests = scanLocalFiles(syncFolders.toMutableList()) syncRequests.putAll(localSyncRequests) + Timber.d("${localSyncRequests.size} request collected from device") if (syncRequests.isEmpty()) { + Timber.d("Fullscan: Nothing to sync") requestCollector.startListeningFiles(applicationContext as Application) return Result.success() } - + Timber.d("Fullscan: ${syncRequests.size} files to sync") requestCollector.queueSyncRequests(syncRequests.values, context) requestCollector.startSynchronization(applicationContext) return Result.success() @@ -185,7 +189,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor val syncedFoldersIds = listRemoteFilesOperation.syncedFoldersId val syncedFileStates = DbHelper.getSyncedFileStatesByFolders(context, syncedFoldersIds) - if (remoteFiles.isNotEmpty() && syncedFileStates.isNotEmpty()) { + if (remoteFiles.isNotEmpty() || syncedFileStates.isNotEmpty()) { val scanner = RemoteContentScanner(context, syncedFolders) return scanner.scanContent(remoteFiles, syncedFileStates) } @@ -211,7 +215,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor val syncedFoldersIds = localFileLister.syncedFoldersId val syncedFileStates = DbHelper.getSyncedFileStatesByFolders(context, syncedFoldersIds) - if (localFiles.isNotEmpty() && syncedFileStates.isNotEmpty()) { + if (localFiles.isNotEmpty() || syncedFileStates.isNotEmpty()) { val scanner = LocalContentScanner(context, syncedFolders) return scanner.scanContent(localFiles, syncedFileStates) } diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index bb8cdf60..27c8024e 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -163,10 +163,6 @@ public class WorkRequestFactory { .putBoolean(FullScanWorker.ACTION_FORCED_SYNC_KEY, forced) .build(); - if (forced) { - builder.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST); - } - return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .setConstraints(constraints) .setInputData(data) -- GitLab From e5a3f6d5dc26e083d304050ef16d13cefc14d7e8 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Fri, 27 Oct 2023 11:05:02 +0200 Subject: [PATCH 13/20] fix NPE from ListFileRemoteOperation --- .../e/drive/periodicScan/ListFileRemoteOperation.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java b/app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java index db14484a..0e07ee51 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java +++ b/app/src/main/java/foundation/e/drive/periodicScan/ListFileRemoteOperation.java @@ -1,6 +1,6 @@ /* * Copyright © CLEUS SAS 2018-2019. - * Copyright © ECORP SAS 2022. + * Copyright © MURENA SAS 2022-2023. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at @@ -26,7 +26,6 @@ import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFolder; import timber.log.Timber; - /** * /!\ Doesn't require NextcloudClient yet * @author Vincent Bourgmayer @@ -59,8 +58,8 @@ public class ListFileRemoteOperation extends RemoteOperation(RemoteOperationResult.ResultCode.OK); if (isContentToScan) { DbHelper.updateSyncedFolders(this.syncedFolders, this.context); - result.setResultData(fileLister.getContentToScan()); } + result.setResultData(fileLister.getContentToScan()); updatedSyncedFoldersId.addAll(fileLister.getSyncedFoldersId()); return result; -- GitLab From 6bc3c1e2c8a9e0ba489b4624ebe530d0df6340ca Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Fri, 27 Oct 2023 11:49:34 +0200 Subject: [PATCH 14/20] restore delay between fullscan feature & change some variables name --- .../receivers/AccountRemoveCallbackReceiver.java | 2 +- .../e/drive/periodicScan/FullScanWorker.kt | 13 +++++++++---- .../java/foundation/e/drive/utils/AppConstants.kt | 5 ++--- .../foundation/e/drive/work/WorkRequestFactory.java | 8 +++----- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java b/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java index bbb594c1..bcfd6b5e 100644 --- a/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java +++ b/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java @@ -107,7 +107,7 @@ public class AccountRemoveCallbackReceiver extends BroadcastReceiver { .remove(AccountManager.KEY_ACCOUNT_TYPE) .remove(SETUP_COMPLETED) .remove(INITIAL_FOLDER_NUMBER) - .remove(AppConstants.KEY_LAST_SYNC_TIME) + .remove(AppConstants.KEY_LAST_SCAN_TIME) .apply(); } diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index 59bb5759..9847b5e2 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -38,6 +38,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor companion object { private const val SYNC_MINIMUM_DELAY = 900000 // min delay between two run in ms. + private const val KEY_LAST_SCAN_TIME = "lastScanTimestamp" const val ACTION_FORCED_SYNC_KEY = "forced_sync" const val UNIQUE_WORK_NAME = "fullScan" } @@ -74,12 +75,16 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor syncRequests.putAll(localSyncRequests) Timber.d("${localSyncRequests.size} request collected from device") + prefs.edit() + .putLong(KEY_LAST_SCAN_TIME, System.currentTimeMillis()) + .apply(); + if (syncRequests.isEmpty()) { - Timber.d("Fullscan: Nothing to sync") + Timber.d("Nothing to sync") requestCollector.startListeningFiles(applicationContext as Application) return Result.success() } - Timber.d("Fullscan: ${syncRequests.size} files to sync") + Timber.d("${syncRequests.size} files to sync") requestCollector.queueSyncRequests(syncRequests.values, context) requestCollector.startSynchronization(applicationContext) return Result.success() @@ -94,7 +99,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor * Check conditions to start periodic scan are respected */ private fun checkStartConditions(account: Account?, prefs : SharedPreferences, requestCollector: SyncRequestCollector): Boolean { - Timber.d("PeriodicScanWorker.checkStartConditions()") + Timber.d("FullScanWorker.checkStartConditions()") if (!isSetupDone(prefs)) return false @@ -124,7 +129,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor * indicate if minimum delay between two periodic scan is respected */ private fun isMinimumDelayRespected(prefs: SharedPreferences): Boolean { - val lastSyncTime = prefs.getLong(AppConstants.KEY_LAST_SYNC_TIME, 0L) + val lastSyncTime = prefs.getLong(KEY_LAST_SCAN_TIME, 0L) val currentTime = System.currentTimeMillis() val deltaTime = currentTime - lastSyncTime diff --git a/app/src/main/java/foundation/e/drive/utils/AppConstants.kt b/app/src/main/java/foundation/e/drive/utils/AppConstants.kt index 49d2b5d6..a42a2470 100644 --- a/app/src/main/java/foundation/e/drive/utils/AppConstants.kt +++ b/app/src/main/java/foundation/e/drive/utils/AppConstants.kt @@ -22,11 +22,10 @@ object AppConstants { const val SETTINGS_SYNC_PROVIDER_AUTHORITY = "foundation.e.drive.providers.SettingsSyncProvider" const val METERED_NETWORK_ALLOWED_AUTHORITY = "foundation.e.drive.providers.MeteredConnectionAllowedProvider" - const val SETUP_COMPLETED = "initService_has_run" + const val SETUP_COMPLETED = "setup_completed" const val INITIAL_FOLDER_NUMBER = "initial_folder_number" const val APPLICATIONS_LIST_FILE_NAME = "packages_list.csv" const val SHARED_PREFERENCE_NAME = "preferences" - const val KEY_LAST_SYNC_TIME = "lastSyncTimestamp" const val ACCOUNT_DATA_NAME = "display_name" const val ACCOUNT_DATA_USED_QUOTA_KEY = "used_quota" const val ACCOUNT_DATA_TOTAL_QUOTA_KEY = "total_quota" @@ -37,7 +36,7 @@ object AppConstants { const val ACCOUNT_USER_ID_KEY = "USERID" const val notificationChannelID = "foundation.e.drive" const val WORK_GENERIC_TAG = "eDrive" - const val WORK_INITIALIZATION_TAG = "eDrive-init" + const val WORK_SETUP_TAG = "eDrive-init" const val CORRUPTED_TIMESTAMP_IN_SECOND = 4294967295L @JvmField diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 27c8024e..924d8d33 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -26,9 +26,7 @@ import androidx.work.Constraints; import androidx.work.Data; import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; -import androidx.work.OutOfQuotaPolicy; import androidx.work.PeriodicWorkRequest; -import androidx.work.WorkerParameters; import java.security.InvalidParameterException; import java.util.concurrent.TimeUnit; @@ -183,7 +181,7 @@ public class WorkRequestFactory { return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .addTag(AppConstants.WORK_SETUP_TAG) .setConstraints(constraints) .build(); } @@ -203,7 +201,7 @@ public class WorkRequestFactory { .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .setInputData(createDataFromSyncedFolder(syncedFolder)) .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .addTag(AppConstants.WORK_SETUP_TAG) .setConstraints(constraints) .build(); } @@ -217,7 +215,7 @@ public class WorkRequestFactory { return new OneTimeWorkRequest.Builder(FinishSetupWorker.class) .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_INITIALIZATION_TAG) + .addTag(AppConstants.WORK_SETUP_TAG) .build(); } -- GitLab From d487caf76d57b2339513e19db8a70d1e1000c466 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Fri, 27 Oct 2023 11:54:25 +0200 Subject: [PATCH 15/20] fix flex time of periodic worker --- .../main/java/foundation/e/drive/periodicScan/FullScanWorker.kt | 2 +- app/src/main/java/foundation/e/drive/utils/AppConstants.kt | 1 + .../main/java/foundation/e/drive/work/WorkRequestFactory.java | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index 9847b5e2..ef7c06dc 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -26,6 +26,7 @@ import foundation.e.drive.periodicScan.contentScanner.RemoteContentScanner import foundation.e.drive.synchronization.SyncProxy import foundation.e.drive.synchronization.SyncRequestCollector import foundation.e.drive.utils.AppConstants +import foundation.e.drive.utils.AppConstants.KEY_LAST_SCAN_TIME import foundation.e.drive.utils.CommonUtils import foundation.e.drive.utils.DavClientProvider import timber.log.Timber @@ -38,7 +39,6 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor companion object { private const val SYNC_MINIMUM_DELAY = 900000 // min delay between two run in ms. - private const val KEY_LAST_SCAN_TIME = "lastScanTimestamp" const val ACTION_FORCED_SYNC_KEY = "forced_sync" const val UNIQUE_WORK_NAME = "fullScan" } diff --git a/app/src/main/java/foundation/e/drive/utils/AppConstants.kt b/app/src/main/java/foundation/e/drive/utils/AppConstants.kt index a42a2470..f3721e60 100644 --- a/app/src/main/java/foundation/e/drive/utils/AppConstants.kt +++ b/app/src/main/java/foundation/e/drive/utils/AppConstants.kt @@ -23,6 +23,7 @@ object AppConstants { const val METERED_NETWORK_ALLOWED_AUTHORITY = "foundation.e.drive.providers.MeteredConnectionAllowedProvider" const val SETUP_COMPLETED = "setup_completed" + const val KEY_LAST_SCAN_TIME = "lastScanTimestamp" const val INITIAL_FOLDER_NUMBER = "initial_folder_number" const val APPLICATIONS_LIST_FILE_NAME = "packages_list.csv" const val SHARED_PREFERENCE_NAME = "preferences" diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 924d8d33..270fb922 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -81,7 +81,7 @@ public class WorkRequestFactory { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); return new PeriodicWorkRequest.Builder(PeriodicScanWorker.class, - 26, TimeUnit.MINUTES, 5, TimeUnit.MINUTES) + 31, TimeUnit.MINUTES, 5, TimeUnit.MINUTES) .setConstraints(constraints) .addTag(AppConstants.WORK_GENERIC_TAG) .build(); -- GitLab From 31845c27b6eaaab17cfe8203f8cfe73a185a8f8f Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 30 Oct 2023 07:40:38 +0000 Subject: [PATCH 16/20] Apply 1 suggestion(s) to 1 file(s) --- .../main/java/foundation/e/drive/periodicScan/FullScanWorker.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index ef7c06dc..186837b4 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -84,6 +84,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor requestCollector.startListeningFiles(applicationContext as Application) return Result.success() } + Timber.d("${syncRequests.size} files to sync") requestCollector.queueSyncRequests(syncRequests.values, context) requestCollector.startSynchronization(applicationContext) -- GitLab From f6c20d6236007daac43a437c91f50c57a572351d Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 30 Oct 2023 07:47:20 +0000 Subject: [PATCH 17/20] Apply 1 suggestion(s) to 1 file(s) --- .../java/foundation/e/drive/periodicScan/FullScanWorker.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index 186837b4..d331e7ba 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -102,10 +102,10 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor private fun checkStartConditions(account: Account?, prefs : SharedPreferences, requestCollector: SyncRequestCollector): Boolean { Timber.d("FullScanWorker.checkStartConditions()") - if (!isSetupDone(prefs)) return false - if (account == null) return false + if (!isSetupDone(prefs)) return false + if (isFileSyncDisabled(account)) return false //@todo could be replaced by checking list of sync folders not empty after loading them val forcedSync = workerParams.inputData.getBoolean(ACTION_FORCED_SYNC_KEY, false) -- GitLab From af73aedbe310cb30817780fa9742b38b5bb1a3ef Mon Sep 17 00:00:00 2001 From: Sayantan Roychowdhury Date: Mon, 30 Oct 2023 13:22:15 +0000 Subject: [PATCH 18/20] Apply 1 suggestion(s) to 1 file(s) --- .../foundation/e/drive/account/setup/FinishSetupWorker.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java index 6a846f7f..c2e21b4c 100644 --- a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java @@ -74,9 +74,11 @@ public class FinishSetupWorker extends Worker { } private void enqueueFullScanWorker(@NonNull final WorkManager workManager) { - workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, + workManager.enqueueUniqueWork( + FullScanWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, - WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FORCED_FULL_SCAN, null)); + WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FORCED_FULL_SCAN, null) + ); } private void enqueueAppListGenerationWorker(@NonNull final WorkManager workManager) { -- GitLab From ae6c1cb5c75b7cbdc4749a9ab99f14df9881a18f Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 30 Oct 2023 14:39:33 +0100 Subject: [PATCH 19/20] apply Jonathan & Hasib suggestions --- .../e/drive/periodicScan/FullScanWorker.kt | 3 - .../e/drive/work/WorkRequestFactory.java | 60 +++++++++++-------- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt index d331e7ba..0a4776ae 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -96,9 +96,6 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor } } - /** - * Check conditions to start periodic scan are respected - */ private fun checkStartConditions(account: Account?, prefs : SharedPreferences, requestCollector: SyncRequestCollector): Boolean { Timber.d("FullScanWorker.checkStartConditions()") diff --git a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java index 270fb922..324b5def 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java +++ b/app/src/main/java/foundation/e/drive/work/WorkRequestFactory.java @@ -8,6 +8,8 @@ package foundation.e.drive.work; +import static androidx.work.BackoffPolicy.LINEAR; +import static java.util.concurrent.TimeUnit.MINUTES; import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_ENABLE; import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_ID; import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_LAST_ETAG; @@ -18,10 +20,11 @@ import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_ME import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_REMOTE_PATH; import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_SCAN_LOCAL; import static foundation.e.drive.account.setup.RootFolderSetupWorker.DATA_KEY_SCAN_REMOTE; +import static foundation.e.drive.utils.AppConstants.WORK_GENERIC_TAG; +import static foundation.e.drive.utils.AppConstants.WORK_SETUP_TAG; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.work.BackoffPolicy; import androidx.work.Constraints; import androidx.work.Data; import androidx.work.NetworkType; @@ -29,7 +32,6 @@ import androidx.work.OneTimeWorkRequest; import androidx.work.PeriodicWorkRequest; import java.security.InvalidParameterException; -import java.util.concurrent.TimeUnit; import foundation.e.drive.account.AccountUserInfoWorker; import foundation.e.drive.account.setup.FinishSetupWorker; @@ -38,7 +40,6 @@ import foundation.e.drive.models.SyncedFolder; import foundation.e.drive.periodicScan.FullScanWorker; import foundation.e.drive.periodicScan.ListAppsWorker; import foundation.e.drive.periodicScan.PeriodicScanWorker; -import foundation.e.drive.utils.AppConstants; public class WorkRequestFactory { public enum WorkType { @@ -52,6 +53,9 @@ public class WorkRequestFactory { ONE_TIME_FINISH_SETUP } + private final static int PERIODIC_WORK_REPEAT_INTERVAL = 30; + private final static int PERIODIC_SCAN_FLEX_TIME = 5; + /** * Build an instance of PeriodicWorkRequest depending of the work type specified * @param type WorkType. Should be FULL_SCAN or PERIODIC_USER_INFO or PERIODIC_APP_LIST @@ -80,11 +84,14 @@ public class WorkRequestFactory { private static PeriodicWorkRequest createPeriodicScanWorkRequest() { final Constraints constraints = createUnmeteredNetworkAndHighBatteryConstraints(); - return new PeriodicWorkRequest.Builder(PeriodicScanWorker.class, - 31, TimeUnit.MINUTES, 5, TimeUnit.MINUTES) - .setConstraints(constraints) - .addTag(AppConstants.WORK_GENERIC_TAG) - .build(); + final PeriodicWorkRequest.Builder workRequestBuilder = new PeriodicWorkRequest.Builder( + PeriodicScanWorker.class, + PERIODIC_WORK_REPEAT_INTERVAL, MINUTES, + PERIODIC_SCAN_FLEX_TIME, MINUTES); + + return workRequestBuilder.setConstraints(constraints) + .addTag(WORK_GENERIC_TAG) + .build(); } /** @@ -97,11 +104,12 @@ public class WorkRequestFactory { .setRequiredNetworkType(NetworkType.CONNECTED) .build(); - return new PeriodicWorkRequest.Builder(AccountUserInfoWorker.class, - 30, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .setConstraints(constraints) - .build(); + final PeriodicWorkRequest.Builder workRequestBuilder = new PeriodicWorkRequest.Builder(AccountUserInfoWorker.class, + PERIODIC_WORK_REPEAT_INTERVAL, MINUTES); + + return workRequestBuilder.addTag(WORK_GENERIC_TAG) + .setConstraints(constraints) + .build(); } /** @@ -140,8 +148,8 @@ public class WorkRequestFactory { private static OneTimeWorkRequest createAppListGenerationWorkRequest() { final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(ListAppsWorker.class); - return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) + return builder.setBackoffCriteria(LINEAR, 2, MINUTES) + .addTag(WORK_GENERIC_TAG) .build(); } @@ -161,10 +169,10 @@ public class WorkRequestFactory { .putBoolean(FullScanWorker.ACTION_FORCED_SYNC_KEY, forced) .build(); - return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + return builder.setBackoffCriteria(LINEAR, 2, MINUTES) .setConstraints(constraints) .setInputData(data) - .addTag(AppConstants.WORK_GENERIC_TAG) + .addTag(WORK_GENERIC_TAG) .build(); } @@ -179,9 +187,9 @@ public class WorkRequestFactory { final OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(AccountUserInfoWorker.class); - return builder.setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_SETUP_TAG) + return builder.setBackoffCriteria(LINEAR, 2, MINUTES) + .addTag(WORK_GENERIC_TAG) + .addTag(WORK_SETUP_TAG) .setConstraints(constraints) .build(); } @@ -198,10 +206,10 @@ public class WorkRequestFactory { return new OneTimeWorkRequest.Builder( RootFolderSetupWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) + .setBackoffCriteria(LINEAR, 2, MINUTES) .setInputData(createDataFromSyncedFolder(syncedFolder)) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_SETUP_TAG) + .addTag(WORK_GENERIC_TAG) + .addTag(WORK_SETUP_TAG) .setConstraints(constraints) .build(); } @@ -213,9 +221,9 @@ public class WorkRequestFactory { @NonNull private static OneTimeWorkRequest createFinishSetupWorkRequest() { return new OneTimeWorkRequest.Builder(FinishSetupWorker.class) - .setBackoffCriteria(BackoffPolicy.LINEAR, 2, TimeUnit.MINUTES) - .addTag(AppConstants.WORK_GENERIC_TAG) - .addTag(AppConstants.WORK_SETUP_TAG) + .setBackoffCriteria(LINEAR, 2, MINUTES) + .addTag(WORK_GENERIC_TAG) + .addTag(WORK_SETUP_TAG) .build(); } -- GitLab From c09d21411721fe9f4e35707c7635aa3b1577e95c Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 30 Oct 2023 14:46:07 +0100 Subject: [PATCH 20/20] apply Sayantan's suggestion --- .../foundation/e/drive/account/setup/FinishSetupWorker.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java index c2e21b4c..1563cf01 100644 --- a/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/FinishSetupWorker.java @@ -8,10 +8,11 @@ package foundation.e.drive.account.setup; +import static android.content.Context.MODE_PRIVATE; import static foundation.e.drive.utils.AppConstants.INITIAL_FOLDER_NUMBER; +import static foundation.e.drive.utils.AppConstants.SHARED_PREFERENCE_NAME; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_APP_LIST; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FORCED_FULL_SCAN; -import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FULL_SCAN; import static foundation.e.drive.work.WorkRequestFactory.WorkType.PERIODIC_SCAN; import android.content.Context; @@ -58,8 +59,7 @@ public class FinishSetupWorker extends Worker { } private void updateSharedPreferences(Context appContext) { - appContext.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, - Context.MODE_PRIVATE) + appContext.getSharedPreferences(SHARED_PREFERENCE_NAME, MODE_PRIVATE) .edit() .putBoolean(AppConstants.SETUP_COMPLETED, true) .putInt(INITIAL_FOLDER_NUMBER, 9) -- GitLab