From ffb97626a3cba204bd799768399f6b9001509cca Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 14 Nov 2023 15:58:15 +0100 Subject: [PATCH 01/20] remove persistent flag --- app/src/main/AndroidManifest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ac42e944..c92784ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,7 +36,6 @@ android:allowBackup="true" android:icon="@drawable/ic_murena_eel" android:label="@string/app_name" - android:persistent="true" android:roundIcon="@drawable/ic_murena_eel" android:requestLegacyExternalStorage="true"> Date: Wed, 15 Nov 2023 11:45:39 +0100 Subject: [PATCH 02/20] add debug command to trigger SyncWorker to upload 10 empty files --- README.md | 26 +++++++- app/src/main/AndroidManifest.xml | 3 +- .../e/drive/receivers/DebugCmdReceiver.java | 64 ++++++++++++++++++- .../e/drive/synchronization/SyncWorker.kt | 13 +++- 4 files changed, 98 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 215c0051..622f319a 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ eDrive can also receive some broadcast intent for different purprose: **Force the synchronization.** ```bash -adb shell am broadcast -a foundation.e.drive.action.FORCE_SYNC --receiver-include-background +adb shell am broadcast -a foundation.e.drive.action.FORCE_SCAN --receiver-include-background ``` **Generate a database dump accessible by the user** @@ -58,14 +58,34 @@ adb shell am broadcast -a foundation.e.drive.action.FORCE_SYNC --receiver-includ adb shell am broadcast -a foundation.e.drive.action.DUMP_DATABASE --receiver-include-background ``` +or Download database directly: + +```bash +adb pull /data/data/foundation.e.drive/databases +``` + **Disable log limit on release build** ```bash - adb shell am broadcast -a foundation.e.drive.action.FULL_LOG_ON_PROD --receiver-include-background --ez full_log_enable true +adb shell am broadcast -a foundation.e.drive.action.FULL_LOG_ON_PROD --receiver-include-background --ez full_log_enable true ``` **Limit log output on release build** *(after previous command)* ```bash - adb shell am broadcast -a foundation.e.drive.action.FULL_LOG_ON_PROD --receiver-include-background --ez full_log_enable false +adb shell am broadcast -a foundation.e.drive.action.FULL_LOG_ON_PROD --receiver-include-background --ez full_log_enable false +``` + +**Test SyncWorker: upload 10 empty files** + +Does not rely on FileObserver or FullScanWorker + +```bash +adb shell am broadcast -a foundation.e.drive.action.TEST_SYNC --receiver-include-background +``` + +**Display logat** + +```bash +adb logcat --pid=$(adb shell pidof -s foundation.e.drive) ``` \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c92784ce..4260d07f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -96,9 +96,10 @@ android:exported="true" tools:ignore="ExportedReceiver"> - + + 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 b4b6cf29..79ded83c 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -8,18 +8,31 @@ package foundation.e.drive.receivers; import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FORCED_FULL_SCAN; +import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_SYNC; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.Environment; import androidx.annotation.NonNull; import androidx.work.ExistingWorkPolicy; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import foundation.e.drive.EdriveApplication; 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.FullScanWorker; +import foundation.e.drive.synchronization.SyncProxy; +import foundation.e.drive.synchronization.SyncRequestCollector; import foundation.e.drive.utils.ReleaseTree; import foundation.e.drive.work.WorkRequestFactory; import timber.log.Timber; @@ -30,17 +43,19 @@ import timber.log.Timber; */ public class DebugCmdReceiver extends BroadcastReceiver { - public static final String ACTION_FORCE_SYNC = "foundation.e.drive.action.FORCE_SYNC"; + public static final String ACTION_TEST_SYNC ="foundation.e.drive.action.TEST_SYNC"; + public static final String ACTION_FORCE_SCAN = "foundation.e.drive.action.FORCE_SCAN"; public static final String ACTION_DUMP_DATABASE = "foundation.e.drive.action.DUMP_DATABASE"; public static final String ACTION_FULL_LOG_ON_PROD = "foundation.e.drive.action.FULL_LOG_ON_PROD"; private static final String FULL_LOG_ENABLE_KEY = "full_log_enable"; @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { Timber.tag(DebugCmdReceiver.class.getSimpleName()).v("onReceive"); + final WorkManager workManager = WorkManager.getInstance(context); + switch (intent.getAction()) { - case ACTION_FORCE_SYNC: + case ACTION_FORCE_SCAN: Timber.d("Force Sync intent received"); - 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, @@ -55,8 +70,51 @@ public class DebugCmdReceiver extends BroadcastReceiver { ReleaseTree.allowDebugLogOnProd(allow_full_log); Timber.d("Allow full log on prod: %s", allow_full_log); break; + case ACTION_TEST_SYNC: + Timber.d("Test SyncWorker.kt started"); + final SyncRequestCollector collector = (SyncRequestCollector) SyncProxy.INSTANCE; + collector.onPeriodicScanStart((EdriveApplication) context.getApplicationContext()); + + File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); + final List requests = generateDummyFileToSync(dir, context); + + if (requests.isEmpty()) return; + + collector.queueSyncRequests(requests, context.getApplicationContext()); + + final OneTimeWorkRequest SyncWorkRequest = WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_SYNC, null); + workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingWorkPolicy.KEEP, + SyncWorkRequest); + break; default: break; } } + + private List generateDummyFileToSync(File dir, Context context) { + final List result = new ArrayList<>(); + final int fileAmount = 10; + final SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(dir.getAbsolutePath(), context); + if (parentFolder == null || !parentFolder.isEnabled()) { + Timber.d("Won't send sync request: no parent are known for n %s", dir.getAbsolutePath()); + return result; + } + for(int index = 0; index < fileAmount; index++) { + final String fileName = "a"+System.currentTimeMillis()/1200+".txt"; + File file = new File(dir.getAbsolutePath(), fileName); + try { + file.createNewFile(); + } catch (IOException exception) { + Timber.d("can't create file"); + continue; + } + final String remotePath = parentFolder.getRemoteFolder()+fileName; + final SyncedFileState fileState = new SyncedFileState(-1, fileName, file.getAbsolutePath(), remotePath, "", 0L, parentFolder.getId(), true, 3); + + final SyncRequest request = new SyncRequest(fileState, SyncRequest.Type.UPLOAD); + result.add(request); + } + return result; + } } \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt index eda410b2..c05a32a4 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt @@ -13,11 +13,15 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.content.Context.NOTIFICATION_SERVICE +import android.content.Intent +import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC +import android.os.Build import androidx.core.app.NotificationCompat import androidx.work.ForegroundInfo import androidx.work.Worker import androidx.work.WorkerParameters +import androidx.work.impl.foreground.SystemForegroundService import com.owncloud.android.lib.common.OwnCloudClient import foundation.e.drive.EdriveApplication import foundation.e.drive.R @@ -84,6 +88,9 @@ class SyncWorker( Timber.w(exception) } + val intent = Intent(applicationContext, SystemForegroundService::class.java) + applicationContext.stopService(intent) + return Result.success() } @@ -144,7 +151,11 @@ class SyncWorker( .build() - return ForegroundInfo(NOTIFICATION_ID, notification) + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_DATA_SYNC) + } else { + ForegroundInfo(NOTIFICATION_ID, notification) + } } private fun createNotificationChannel() { -- GitLab From cdbc0f3e462a24b344bcc99c5f2375008e697e7c Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 22 Nov 2023 10:21:21 +0100 Subject: [PATCH 03/20] Code cleaning - apply Jonathan's suggestion: remove unexpected ; symbol - apply Jonathan's suggestion: replace import with wildcard by correct import instruction - remove useless and annoying log input - remove useless call to stopService --- .../java/foundation/e/drive/synchronization/SyncTask.kt | 6 ++++-- .../java/foundation/e/drive/synchronization/SyncWorker.kt | 5 ----- app/src/main/java/foundation/e/drive/utils/CommonUtils.java | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt index d37317e8..497d547b 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt @@ -17,7 +17,9 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo import foundation.e.drive.database.DbHelper import foundation.e.drive.database.FailedSyncPrefsManager import foundation.e.drive.models.SyncRequest -import foundation.e.drive.models.SyncRequest.Type.* +import foundation.e.drive.models.SyncRequest.Type.UPLOAD +import foundation.e.drive.models.SyncRequest.Type.DISABLE_SYNCING +import foundation.e.drive.models.SyncRequest.Type.DOWNLOAD import foundation.e.drive.models.SyncWrapper import foundation.e.drive.synchronization.tasks.UploadFileOperation import foundation.e.drive.utils.CommonUtils @@ -143,7 +145,7 @@ class SyncTask( if (!success) { if (request.operationType == SyncRequest.Type.UPLOAD) { val filePath = fileState.localPath - if (filePath.isEmpty()) return; + if (filePath.isEmpty()) return val file = File(filePath) if (file.length() >= UploadFileOperation.FILE_SIZE_FLOOR_FOR_CHUNKED) return } diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt index c05a32a4..5189c127 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt @@ -13,7 +13,6 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.content.Context.NOTIFICATION_SERVICE -import android.content.Intent import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC import android.os.Build import androidx.core.app.NotificationCompat @@ -21,7 +20,6 @@ import androidx.work.ForegroundInfo import androidx.work.Worker import androidx.work.WorkerParameters -import androidx.work.impl.foreground.SystemForegroundService import com.owncloud.android.lib.common.OwnCloudClient import foundation.e.drive.EdriveApplication import foundation.e.drive.R @@ -88,9 +86,6 @@ class SyncWorker( Timber.w(exception) } - val intent = Intent(applicationContext, SystemForegroundService::class.java) - applicationContext.stopService(intent) - return Result.success() } 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 a9fd0c00..38bb1293 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -161,7 +161,6 @@ public abstract class CommonUtils { * @return True if there is connection, false either */ public static boolean haveNetworkConnection(@NonNull Context context, boolean meteredNetworkAllowed) { - Timber.v("haveNetworkConnection()"); final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); final NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork()); -- GitLab From f4f7629192adf5c9af422b466bde0aae1cfac8a0 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 22 Nov 2023 16:42:39 +0100 Subject: [PATCH 04/20] Update Readme and add bash scripts for developer/tester --- README.md | 20 ++++++++- dev_tools.sh | 100 +++++++++++++++++++++++++++++++++++++++++++++ registerAccount.sh | 68 ++++++++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100755 dev_tools.sh create mode 100755 registerAccount.sh diff --git a/README.md b/README.md index 622f319a..c7d430fa 100644 --- a/README.md +++ b/README.md @@ -88,4 +88,22 @@ adb shell am broadcast -a foundation.e.drive.action.TEST_SYNC --receiver-include ```bash adb logcat --pid=$(adb shell pidof -s foundation.e.drive) -``` \ No newline at end of file +``` + +You can also use the script `dev-tools.sh` to run those command. Use : `./dev-tools.sh -h` to display options + +### local NC for testing + +Use following documentation to set up a local NC instance + +https://gitlab.e.foundation/internal/wiki/-/wikis/qa-team/how-to-run-local-nextcloud + +`docker run -d -p 8080:80 -e NEXTCLOUD_TRUSTED_DOMAINS=":8080" -e SQLITE_DATABASE=nc -e NEXTCLOUD_ADMIN_USER=admin -e NEXTCLOUD_ADMIN_PASSWORD=admin nextcloud: +` + +Then you can use Wireshark by example to collect network packet. +Example of filter for wireshark: +`(ip.src == && ip.dst == ) || (ip.dst == && ip.src == ) && http` + + +*note: replace , and by values* \ No newline at end of file diff --git a/dev_tools.sh b/dev_tools.sh new file mode 100755 index 00000000..2f7f7a5c --- /dev/null +++ b/dev_tools.sh @@ -0,0 +1,100 @@ + +# Author Vincent Bourgmayer +# 2023 November 22nd + +function printHelp() { + echo "Utilisation: ./eDrive_dev_tools.sh [opt] [(optionnal:) value] + Note: This script strongly rely on ADB, so it won't work if ADB is not installed + + Options list: + -a : add Account into the device + -c : clear eDrive's data + -C : clear adb logcat + -d : dump database (generate a database dumb on the device. The dump is reachable by the user) + -f : Trigger fullScan work (scan cloud & device then try to sync changed files) + -h : print this help + -L : (required value: true|false) : true: enable/ false: disable full log + -l : (option: --clear) : --clear: clear logcat before. Otherwise just display logcat. Default: false + -p : Pull database directory from device into current computer folder + -s : test sync : Create 10 empty files in 'Document' folder and try to upload them + "; +} + + +function registerAccount() { + echo "calling script to add account into device + + /!\ Device need to be connecter to WI_FI + + /!\ In order to let it work, + check that credentials & server URL + are set in registerAccount2.sh + + /i\ please also consider, that the script will need to be updated if UI + changes + "; + + + ./registerAccount.sh +} + +function setFullLog() { + if [ -z "$1" ]; then + echo "The parameter -L require a value (true|false)" + elif [ "$1" != "true" ] && [ "$1" != "false" ]; then + echo "Invalid parameter: $1. You need to provide: (true|false)" + else + echo "Sending broacast with $1 as parameter" + adb shell am broadcast -a foundation.e.drive.action.FULL_LOG_ON_PROD --receiver-include-background --ez full_log_enable "$1" + fi +} + +function displayLogcat() { + adb logcat --pid=$(adb shell pidof -s foundation.e.drive) +} + +function clearLogcat() { + adb logcat --clear +} + +function pullDatabase() { + adb pull /data/data/foundation.e.drive/databases +} + +function clearAppData() { + echo "clear eDrive's data"; + adb shell pm clear foundation.e.drive +} + +function dumpDatabase() { + echo "Dumping database" + adb shell am broadcast -a foundation.e.drive.action.DUMP_DATABASE --receiver-include-background +} + +function forceFullScan() { + adb shell am broadcast -a foundation.e.drive.action.FORCE_SCAN --receiver-include-background +} + +function testSync() { + adb shell am broadcast -a foundation.e.drive.action.TEST_SYNC --receiver-include-background +} + +while getopts acCdfhL:lps flag +do + case "${flag}" in + a) registerAccount;; + c) clearAppData;; + C) clearLogcat;; + d) dumpDatabase;; + f) forceFullScan;; + h) printHelp;; + l) displayLogcat;; + L) setFullLog ${OPTARG};; + p) pullDatabase;; + s) testSync;; + esac +done + +echo "|----FINISHED----|" +exit 0 + diff --git a/registerAccount.sh b/registerAccount.sh new file mode 100755 index 00000000..ae8b0cb4 --- /dev/null +++ b/registerAccount.sh @@ -0,0 +1,68 @@ + +# Open Add account settings page (doesn't work if already opened and not closed) +adb shell am start -a android.settings.ADD_ACCOUNT_SETTINGS + +sleep 1 +# Select /e/ account as it is the first one in the type list +adb shell input keyevent TAB +adb shell input keyevent TAB +sleep 1 + +# Open the /e/ account : add account form +adb shell input keyevent ENTER + + +# CREDENTIALS & SERVER URL + +MAIL="PUT YOUR VALUE" +PWD="PUT YOUR VALUE" +SERVER_URI="PUT YOUR VALUE" + +sleep 1 +#Insert Login +adb shell input text $MAIL +adb shell input keyevent TAB + +sleep 1 +#Insert PWD +adb shell input text $PWD + +## IF NO server URI +if [ -z $SERVER_URI ] +then + adb shell input keyevent TAB + adb shell input keyevent ENTER +else + + # Move across element + adb shell input keyevent TAB + adb shell input keyevent TAB + adb shell input keyevent TAB + + # Enter server URI + adb shell input keyevent ENTER + adb shell input keyevent TAB + adb shell input text $SERVER_URI + + # Move again to login btn + adb shell input keyevent TAB + adb shell input keyevent TAB + adb shell input keyevent TAB + adb shell input keyevent TAB + adb shell input keyevent TAB + adb shell input keyevent ENTER +fi + + +## OLD WAY to put server uri + +#Remove server Uri +#adb shell input keyevent KEYCODE_MOVE_END +#adb shell input keyevent --longpress $(printf 'KEYCODE_DEL %.0s' {1..250}) +#Add new server Uri +#adb shell input text $SERVER_URI + +#Validate the form +#sleep 1 +#adb shell input keyevent TAB +#adb shell input keyevent ENTER -- GitLab From 57997436b4fd226ff1e33e9872758dc5cdf15f04 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 30 Nov 2023 16:14:46 +0100 Subject: [PATCH 05/20] factorize method that enqueue Worker in a dedicated class: WorkerUtils.kt --- .../account/receivers/AccountAddedReceiver.kt | 5 +- .../account/setup/FinishSetupWorker.java | 33 ++------- .../e/drive/receivers/DebugCmdReceiver.java | 20 ++---- .../e/drive/synchronization/SyncProxy.kt | 9 +-- .../foundation/e/drive/utils/CommonUtils.java | 43 +----------- .../foundation/e/drive/work/WorkerUtils.kt | 69 +++++++++++++++++++ 6 files changed, 84 insertions(+), 95 deletions(-) create mode 100644 app/src/main/java/foundation/e/drive/work/WorkerUtils.kt 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 4e0b9248..bcf6e96e 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 @@ -21,6 +21,7 @@ import foundation.e.drive.utils.CommonUtils import foundation.e.drive.utils.DavClientProvider import foundation.e.drive.utils.RootSyncedFolderProvider import foundation.e.drive.work.WorkRequestFactory.* +import foundation.e.drive.work.WorkerUtils import timber.log.Timber /** @@ -51,7 +52,7 @@ class AccountAddedReceiver() : BroadcastReceiver() { if (registerSetupWorkers(context)) { DavClientProvider.getInstance().cleanUp() - CommonUtils.registerPeriodicUserInfoChecking(WorkManager.getInstance(context)) + WorkerUtils.enqueuePeriodicUserInfoFetching(WorkManager.getInstance(context)) } } @@ -118,7 +119,7 @@ class AccountAddedReceiver() : BroadcastReceiver() { val rootSyncedFolderList: List = RootSyncedFolderProvider.getSyncedFolderRoots(context) - if (rootSyncedFolderList.isNullOrEmpty()) { + if (rootSyncedFolderList.isEmpty()) { return null } 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 1563cf01..3a847973 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 @@ -11,23 +11,16 @@ 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.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; +import foundation.e.drive.work.WorkerUtils; import timber.log.Timber; /** @@ -68,26 +61,8 @@ public class FinishSetupWorker extends Worker { private void enqueueWorkers(@NonNull final Context appContext) { final WorkManager workManager = WorkManager.getInstance(appContext); - enqueueAppListGenerationWorker(workManager); - enqueueFullScanWorker(workManager); - enqueuePeriodicFileScanWorker(workManager); - } - - private void enqueueFullScanWorker(@NonNull final WorkManager workManager) { - workManager.enqueueUniqueWork( - FullScanWorker.UNIQUE_WORK_NAME, - ExistingWorkPolicy.KEEP, - WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FORCED_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)); + WorkerUtils.enqueueOneTimeAppListGenerator(workManager); + WorkerUtils.enqueueOneTimeFullScan(workManager, false); + WorkerUtils.enqueuePeriodicFullScan(workManager); } } \ No newline at end of file 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 79ded83c..b3ee483b 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -7,17 +7,12 @@ */ package foundation.e.drive.receivers; -import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_FORCED_FULL_SCAN; -import static foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_SYNC; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Environment; import androidx.annotation.NonNull; -import androidx.work.ExistingWorkPolicy; -import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; import java.io.File; @@ -30,11 +25,10 @@ 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.FullScanWorker; import foundation.e.drive.synchronization.SyncProxy; import foundation.e.drive.synchronization.SyncRequestCollector; import foundation.e.drive.utils.ReleaseTree; -import foundation.e.drive.work.WorkRequestFactory; +import foundation.e.drive.work.WorkerUtils; import timber.log.Timber; /** @@ -56,10 +50,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { switch (intent.getAction()) { case ACTION_FORCE_SCAN: Timber.d("Force Sync intent received"); - final OneTimeWorkRequest fullScanWorkRequest = WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_FORCED_FULL_SCAN, null); - workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, - ExistingWorkPolicy.KEEP, - fullScanWorkRequest); + WorkerUtils.enqueueOneTimeFullScan(workManager, true); break; case ACTION_DUMP_DATABASE: Timber.d("Dump database intent received"); @@ -82,10 +73,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { collector.queueSyncRequests(requests, context.getApplicationContext()); - final OneTimeWorkRequest SyncWorkRequest = WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_SYNC, null); - workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, - ExistingWorkPolicy.KEEP, - SyncWorkRequest); + collector.startSynchronization(context.getApplicationContext()); break; default: break; @@ -100,7 +88,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { Timber.d("Won't send sync request: no parent are known for n %s", dir.getAbsolutePath()); return result; } - for(int index = 0; index < fileAmount; index++) { + for (int index = 0; index < fileAmount; index++) { final String fileName = "a"+System.currentTimeMillis()/1200+".txt"; File file = new File(dir.getAbsolutePath(), fileName); try { diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt index ef829bda..3e9a7c00 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt @@ -9,14 +9,12 @@ package foundation.e.drive.synchronization import android.app.Application import android.content.Context -import androidx.work.ExistingWorkPolicy import androidx.work.WorkManager import foundation.e.drive.EdriveApplication import foundation.e.drive.database.FailedSyncPrefsManager import foundation.e.drive.models.SyncRequest import foundation.e.drive.models.SyncWrapper -import foundation.e.drive.work.WorkRequestFactory -import foundation.e.drive.work.WorkRequestFactory.WorkType.ONE_TIME_SYNC +import foundation.e.drive.work.WorkerUtils import timber.log.Timber import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedQueue @@ -133,10 +131,7 @@ object SyncProxy: SyncRequestCollector, SyncManager { } if (previousSyncState != SyncState.SYNCHRONIZING) { - val workManager = WorkManager.getInstance(context) - val workRequest = WorkRequestFactory.getOneTimeWorkRequest(ONE_TIME_SYNC, null) - - workManager.enqueueUniqueWork(SyncWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, workRequest) + WorkerUtils.enqueueOneTimeSync(WorkManager.getInstance(context)) } } 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 38bb1293..0ecf53c8 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -1,6 +1,6 @@ /* * Copyright © CLEUS SAS 2018-2019. - * Copyright © ECORP SAS 2022-2023. + * 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 @@ -14,7 +14,6 @@ import android.accounts.AccountManager; import android.annotation.SuppressLint; import android.app.NotificationChannel; import android.app.NotificationManager; -import android.app.Service; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ContentResolver; @@ -31,9 +30,6 @@ import java.text.StringCharacterIterator; import java.util.Locale; import foundation.e.drive.R; -import foundation.e.drive.account.AccountUserInfoWorker; -import foundation.e.drive.work.WorkRequestFactory; -import timber.log.Timber; import static foundation.e.drive.utils.AppConstants.MEDIA_SYNC_PROVIDER_AUTHORITY; import static foundation.e.drive.utils.AppConstants.METERED_NETWORK_ALLOWED_AUTHORITY; @@ -41,10 +37,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.PeriodicWorkRequest; -import androidx.work.WorkManager; - /** * @author Vincent Bourgmayer @@ -54,22 +46,6 @@ import androidx.work.WorkManager; */ public abstract class CommonUtils { - /** - * Set ServiceUncaughtExceptionHandler to be the MainThread Exception Handler - * Or update the service which use it - * todo: check if the ServiceExceptionHandler could be remove - * @param service current service - */ - public static void setServiceUnCaughtExceptionHandler(@NonNull Service service) { - Thread.UncaughtExceptionHandler defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); - if (defaultUEH != null && ServiceExceptionHandler.class.getSimpleName().equals(defaultUEH.getClass().getSimpleName())) { - ((ServiceExceptionHandler) defaultUEH).setService(service); - } else { - Thread.setDefaultUncaughtExceptionHandler(new ServiceExceptionHandler(service)); - } - } - - /** * This method retrieve Account corresponding to account's name and type * @@ -149,10 +125,6 @@ public abstract class CommonUtils { return ContentResolver.getSyncAutomatically(account, METERED_NETWORK_ALLOWED_AUTHORITY); } - /* methods relative to file */ - - - /** * Tell if there is internet connection * @@ -216,17 +188,6 @@ public abstract class CommonUtils { Toast.LENGTH_SHORT).show(); } - - /** - * Job for Widget & notification about quota - * - * @param workManager component used to register worker - */ - public static void registerPeriodicUserInfoChecking(@NonNull WorkManager workManager) { - final PeriodicWorkRequest workRequest = WorkRequestFactory.getPeriodicWorkRequest(WorkRequestFactory.WorkType.PERIODIC_USER_INFO); - workManager.enqueueUniquePeriodicWork(AccountUserInfoWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.UPDATE, workRequest); - } - /** * Function for get build props through reflection * @@ -246,4 +207,4 @@ public abstract class CommonUtils { } return value == null ? "" : value; } -} +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt b/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt new file mode 100644 index 00000000..56b24fcc --- /dev/null +++ b/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt @@ -0,0 +1,69 @@ +/* + * 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.work + +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.ExistingWorkPolicy +import androidx.work.WorkManager +import foundation.e.drive.account.AccountUserInfoWorker +import foundation.e.drive.periodicScan.FullScanWorker +import foundation.e.drive.synchronization.SyncWorker +import foundation.e.drive.work.WorkRequestFactory.WorkType + +/** + * @author Vincent Bourgmayer + */ +object WorkerUtils { + + @JvmStatic + fun enqueuePeriodicUserInfoFetching(workManager: WorkManager) { + val request = WorkRequestFactory.getPeriodicWorkRequest(WorkType.PERIODIC_USER_INFO) + workManager.enqueueUniquePeriodicWork(AccountUserInfoWorker.UNIQUE_WORK_NAME, + ExistingPeriodicWorkPolicy.UPDATE, + request) + } + + @JvmStatic + fun enqueuePeriodicFullScan(workManager: WorkManager) { + val request = WorkRequestFactory.getPeriodicWorkRequest(WorkType.PERIODIC_SCAN) + workManager.enqueueUniquePeriodicWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingPeriodicWorkPolicy.KEEP, + request) + } + + @JvmStatic + fun enqueueOneTimeFullScan(workManager: WorkManager, isForced: Boolean) { + if (isForced) { + val request = WorkRequestFactory.getOneTimeWorkRequest(WorkType.ONE_TIME_FORCED_FULL_SCAN, + null) + workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingWorkPolicy.REPLACE, + request) + return + } + + val request = WorkRequestFactory.getOneTimeWorkRequest(WorkType.ONE_TIME_FULL_SCAN, + null) + workManager.enqueueUniqueWork(FullScanWorker.UNIQUE_WORK_NAME, + ExistingWorkPolicy.KEEP, + request) + } + + @JvmStatic + fun enqueueOneTimeAppListGenerator(workManager: WorkManager) { + val request = WorkRequestFactory.getOneTimeWorkRequest(WorkType.ONE_TIME_APP_LIST, + null) + workManager.enqueue(request) + } + + @JvmStatic + fun enqueueOneTimeSync(workManager: WorkManager) { + val request = WorkRequestFactory.getOneTimeWorkRequest(WorkType.ONE_TIME_SYNC, null) + workManager.enqueueUniqueWork(SyncWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, request) + } +} \ No newline at end of file -- GitLab From 53b1841de904aa6eeb021ccfff3cb92675079398 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 30 Nov 2023 16:43:39 +0100 Subject: [PATCH 06/20] cancell all workers on eDrive update, then enqueue periodic work changes in bootCompleteReceiver: - cancel all worker without using tag - add debug instruction in bootCompleteReceiver - Update one preferences after app update + remove call to Timber.tag in DBHelper --- .../foundation/e/drive/database/DbHelper.java | 1 - .../receivers/BootCompletedReceiver.java | 71 +++++++++++++++---- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/database/DbHelper.java b/app/src/main/java/foundation/e/drive/database/DbHelper.java index a71ca586..5a4ac077 100644 --- a/app/src/main/java/foundation/e/drive/database/DbHelper.java +++ b/app/src/main/java/foundation/e/drive/database/DbHelper.java @@ -47,7 +47,6 @@ public final class DbHelper extends SQLiteOpenHelper { */ public DbHelper(@NonNull Context context){ super(context, DATABASE_NAME, null, DATABASE_VERSION); - Timber.tag(DbHelper.class.getSimpleName()); } /** diff --git a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java index 1f67e5a7..e4c2a919 100644 --- a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java @@ -16,12 +16,14 @@ import android.content.SharedPreferences; import android.database.sqlite.SQLiteException; import androidx.annotation.NonNull; +import androidx.work.WorkManager; import foundation.e.drive.BuildConfig; import foundation.e.drive.database.DbHelper; import foundation.e.drive.synchronization.SyncProxy; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; +import foundation.e.drive.work.WorkerUtils; import timber.log.Timber; /** @@ -31,27 +33,30 @@ import timber.log.Timber; public class BootCompletedReceiver extends BroadcastReceiver { private static final String DATE_SYSTEM_PROPERTY = "ro.build.date"; private static final String PREF_VERSION_CODE = "VERSION_CODE"; + private static final String OLD_SETUP_COMPLETED_PREF_KEY ="initService_has_run"; + + private static final int VERSION_CODE_FOR_UPDATE_1 = 1002000; + private static final int VERSION_CODE_FOR_UPDATE_2 = 1003017; + @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { final String action = intent.getAction(); - Timber.tag(BootCompletedReceiver.class.getSimpleName()).v("onReceive(...)"); - final SharedPreferences pref = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); + Timber.v("onReceive(...)"); + final SharedPreferences prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { final String currentDateProp = CommonUtils.getProp(DATE_SYSTEM_PROPERTY); - if (isOsUpdated(pref, currentDateProp)) { // App is persistent so can only be updated (by replacement) on OS update + if (isOsUpdated(prefs, currentDateProp)) { // App is persistent so can only be updated (by replacement) on OS update handleOsUpdate(context); } - if (pref.getBoolean(AppConstants.SETUP_COMPLETED, false) - && BuildConfig.VERSION_CODE > pref.getInt(PREF_VERSION_CODE, 1002000)) { - pref.edit().putInt(PREF_VERSION_CODE, BuildConfig.VERSION_CODE).apply(); - try { - DbHelper.cleanSyncedFileStateTableAfterUpdate(context); - } catch (SQLiteException exception) { - Timber.e(exception); - } + updatePreferences(prefs); + + final int lastSavedVersionCode = prefs.getInt(PREF_VERSION_CODE, VERSION_CODE_FOR_UPDATE_1); + if (isEdriveUpdated(lastSavedVersionCode) && isSetupCompleted(prefs)) { + onEdriveUpdate(lastSavedVersionCode, context); + prefs.edit().putInt(PREF_VERSION_CODE, BuildConfig.VERSION_CODE).apply(); } SyncProxy.INSTANCE.startListeningFiles((Application) context.getApplicationContext()); @@ -63,17 +68,57 @@ public class BootCompletedReceiver extends BroadcastReceiver { dbHelper.getWritableDatabase().close(); //Force upgrade of db. } + private void updatePreferences(@NonNull SharedPreferences prefs) { + if (prefs.getBoolean(OLD_SETUP_COMPLETED_PREF_KEY, false)) { + Timber.i("Update setup complete preferences"); + prefs + .edit() + .remove(OLD_SETUP_COMPLETED_PREF_KEY) + .putBoolean(AppConstants.SETUP_COMPLETED, true) + .apply(); + + } + } + /** * Force reinitialization, upgrade of DB in case of OS update - * todo remove when setPersistentFlag=true will be removed * @param context Context used to start InitializationService */ private void handleOsUpdate(@NonNull Context context) { forceDBUpdate(context); } + /** @noinspection SpellCheckingInspection*/ + private boolean isEdriveUpdated(int oldVersionCode) { + Timber.d("isEdriveUpdated (%s > %s) ?", BuildConfig.VERSION_CODE, oldVersionCode); + return BuildConfig.VERSION_CODE > oldVersionCode; + } + + private boolean isSetupCompleted(@NonNull SharedPreferences prefs) { + return prefs.getBoolean(AppConstants.SETUP_COMPLETED, false); + } + + private void onEdriveUpdate(int oldVersionCode, @NonNull Context context) { + if (oldVersionCode <= VERSION_CODE_FOR_UPDATE_1) { + try { + DbHelper.cleanSyncedFileStateTableAfterUpdate(context); + } catch (SQLiteException exception) { + Timber.e(exception); + } + } + + if (oldVersionCode <= VERSION_CODE_FOR_UPDATE_2) { + Timber.d("Triggered the update 2 from: %s", oldVersionCode); + final WorkManager workManager= WorkManager.getInstance(context); + workManager.cancelAllWork(); + + WorkerUtils.enqueuePeriodicFullScan(workManager); + WorkerUtils.enqueuePeriodicUserInfoFetching(workManager); + } + } + private boolean isOsUpdated(@NonNull SharedPreferences prefs, @NonNull String currentDateProp) { final String lastKnownDateProp = prefs.getString(DATE_SYSTEM_PROPERTY, ""); return !currentDateProp.equals(lastKnownDateProp); } -} +} \ No newline at end of file -- GitLab From 346b61d566b61187f690aa5f370c165f4efb87d4 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Thu, 30 Nov 2023 11:51:58 +0100 Subject: [PATCH 07/20] Update app/build.gradle: - update version number to v1.4.0 - Update dependencies's version --- app/build.gradle | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2073fe13..eaff7661 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,10 +3,9 @@ plugins { id 'org.jetbrains.kotlin.android' } - def versionMajor = 1 -def versionMinor = 3 -def versionPatch = 16 +def versionMinor = 4 +def versionPatch = 0 def getTestProp(String propName) { def result = "" @@ -97,16 +96,15 @@ dependencies { implementation 'com.github.nextcloud:android-library:2.13.0' implementation "commons-httpclient:commons-httpclient:3.1@jar" implementation fileTree(include: ['*.jar'], dir: 'libs') - api 'androidx.annotation:annotation:1.6.0' - implementation 'androidx.core:core:1.10.1' + api 'androidx.annotation:annotation:1.7.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation "androidx.constraintlayout:constraintlayout:2.1.4" - implementation 'com.google.android.material:material:1.9.0' + implementation 'com.google.android.material:material:1.10.0' implementation 'com.github.bumptech.glide:glide:4.15.1' implementation 'com.github.bumptech.glide:annotations:4.15.1' - implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.core:core-ktx:1.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1' - implementation "androidx.work:work-runtime:2.8.1" + implementation "androidx.work:work-runtime:2.9.0" implementation 'androidx.test:core:1.5.0' implementation 'com.jakewharton.timber:timber:5.0.1' implementation 'foundation.e:elib:0.0.1-alpha11' @@ -114,7 +112,7 @@ dependencies { androidTestImplementation 'androidx.test:runner:1.5.2' androidTestImplementation 'androidx.test:rules:1.5.0' - androidTestImplementation 'androidx.annotation:annotation:1.6.0' + androidTestImplementation 'androidx.annotation:annotation:1.7.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'junit:junit:4.13.2' @@ -124,5 +122,5 @@ dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'org.robolectric:robolectric:4.7.3' testImplementation 'org.mockito:mockito-core:5.0.0' - testImplementation 'androidx.work:work-testing:2.8.1' + testImplementation 'androidx.work:work-testing:2.9.0' } -- GitLab From caac059797fbfa854b4330ef3f4af6970317341e Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 21 Nov 2023 15:25:59 +0100 Subject: [PATCH 08/20] factorize getAccount(accountName: String, context: Context) method in accountUtils Remove CommonUtils.getAccount(accountName, accountType, Context) Update CommonUtils's licence header to use MURENA SAS instead of ECORP SAS Remove another unused method from CommonUtils --- .../{utils => account}/AccountUtils.java | 30 +++++++++++++++++-- .../account/receivers/AccountAddedReceiver.kt | 9 +++--- .../account/setup/RootFolderSetupWorker.java | 17 ++--------- .../e/drive/activity/AccountsActivity.java | 2 +- .../e/drive/periodicScan/FullScanWorker.kt | 12 ++------ .../e/drive/synchronization/SyncWorker.kt | 15 ++-------- .../foundation/e/drive/utils/CommonUtils.java | 21 +------------ .../e/drive/widgets/EDriveWidget.java | 2 +- 8 files changed, 41 insertions(+), 67 deletions(-) rename app/src/main/java/foundation/e/drive/{utils => account}/AccountUtils.java (57%) diff --git a/app/src/main/java/foundation/e/drive/utils/AccountUtils.java b/app/src/main/java/foundation/e/drive/account/AccountUtils.java similarity index 57% rename from app/src/main/java/foundation/e/drive/utils/AccountUtils.java rename to app/src/main/java/foundation/e/drive/account/AccountUtils.java index d9b944d9..236f70ae 100644 --- a/app/src/main/java/foundation/e/drive/utils/AccountUtils.java +++ b/app/src/main/java/foundation/e/drive/account/AccountUtils.java @@ -14,12 +14,14 @@ * along with this program. If not, see . */ -package foundation.e.drive.utils; +package foundation.e.drive.account; import static foundation.e.drive.utils.AppConstants.ACCOUNT_DATA_GROUPS; import android.accounts.Account; import android.accounts.AccountManager; +import android.content.Context; +import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -27,8 +29,10 @@ import androidx.annotation.Nullable; import java.util.Arrays; import java.util.Optional; -public class AccountUtils { +import foundation.e.drive.R; +import foundation.e.drive.utils.AppConstants; +public class AccountUtils { @NonNull public static Optional getPremiumGroup(@NonNull AccountManager accountManager, @Nullable Account account) { @@ -48,4 +52,26 @@ public class AccountUtils { .filter(group -> group.contains("premium-")) .findFirst(); } + + public static @Nullable Account getAccount(@NonNull final Context context) { + final SharedPreferences prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); + final String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); + + return getAccount(accountName, context); + } + + public static @Nullable Account getAccount(@NonNull final String accountName, @NonNull final Context context) { + if (accountName.isEmpty()) return null; + + final AccountManager accountManager = AccountManager.get(context); + final String accountType = context.getString(R.string.eelo_account_type); + + final Account[] accounts = accountManager.getAccountsByType(accountType); + for (int i = -1, size = accounts.length; ++i < size; ) { + if (accounts[i].name.equals(accountName)) { + return accounts[i]; + } + } + return null; + } } 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 bcf6e96e..b8d679f9 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 @@ -16,8 +16,8 @@ import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager import foundation.e.drive.R import foundation.e.drive.models.SyncedFolder +import foundation.e.drive.account.AccountUtils import foundation.e.drive.utils.AppConstants -import foundation.e.drive.utils.CommonUtils import foundation.e.drive.utils.DavClientProvider import foundation.e.drive.utils.RootSyncedFolderProvider import foundation.e.drive.work.WorkRequestFactory.* @@ -81,7 +81,7 @@ class AccountAddedReceiver() : BroadcastReceiver() { return false } - if (!isExistingAccount(accountName, accountType, context)) { + if (!isExistingAccount(accountName, context)) { Timber.w("No account exist for username: %s ", accountType, accountName) return false } @@ -97,9 +97,8 @@ class AccountAddedReceiver() : BroadcastReceiver() { return prefs.getBoolean(AppConstants.SETUP_COMPLETED, false) } - private fun isExistingAccount(accountName: String, accountType: String, context: Context): Boolean { - val account = CommonUtils.getAccount(accountName, accountType, AccountManager.get(context)) - return account != null + private fun isExistingAccount(accountName: String, context: Context): Boolean { + return AccountUtils.getAccount(accountName, context) != null } private fun registerSetupWorkers(context: Context): Boolean { diff --git a/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java index 6488eeb5..5c03617b 100644 --- a/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java @@ -9,9 +9,7 @@ package foundation.e.drive.account.setup; import android.accounts.Account; -import android.accounts.AccountManager; import android.content.Context; -import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -25,10 +23,9 @@ import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation; import java.io.File; -import foundation.e.drive.R; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFolder; -import foundation.e.drive.utils.AppConstants; +import foundation.e.drive.account.AccountUtils; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; import timber.log.Timber; @@ -62,7 +59,7 @@ public class RootFolderSetupWorker extends Worker { public Result doWork() { try { final Context context = getApplicationContext(); - final Account account = getAccount(); + final Account account = AccountUtils.getAccount(getApplicationContext()); if (account == null) { Timber.d("doWork(): Can't get valid account"); return Result.failure(); @@ -129,14 +126,4 @@ public class RootFolderSetupWorker extends Worker { return result; } - - @Nullable - private Account getAccount() { - final SharedPreferences prefs = getApplicationContext().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); - - if (accountName.isEmpty()) return null; - return CommonUtils.getAccount(accountName, accountType, AccountManager.get(getApplicationContext())); - } } diff --git a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java index 5929f370..7dd2176b 100644 --- a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java +++ b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java @@ -34,7 +34,7 @@ import com.owncloud.android.lib.common.OwnCloudClient; import foundation.e.drive.R; import foundation.e.drive.databinding.ActivityAccountsBinding; -import foundation.e.drive.utils.AccountUtils; +import foundation.e.drive.account.AccountUtils; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; import foundation.e.drive.widgets.EDriveWidget; 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 49cc9c53..e2f21335 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -8,7 +8,6 @@ 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 @@ -16,7 +15,6 @@ 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 @@ -25,6 +23,7 @@ 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.account.AccountUtils import foundation.e.drive.utils.AppConstants import foundation.e.drive.utils.AppConstants.KEY_LAST_SCAN_TIME import foundation.e.drive.utils.CommonUtils @@ -51,7 +50,7 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE ) - val account = loadAccount(prefs) + val account = AccountUtils.getAccount(applicationContext) val startAllowed = checkStartConditions(account, prefs, requestCollector) if (!startAllowed) { @@ -115,13 +114,6 @@ class FullScanWorker(private val context: Context, private val workerParams: Wor 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 */ diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt index 5189c127..861d7b7c 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt @@ -8,7 +8,6 @@ package foundation.e.drive.synchronization import android.accounts.Account -import android.accounts.AccountManager import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context @@ -23,8 +22,7 @@ import androidx.work.WorkerParameters import com.owncloud.android.lib.common.OwnCloudClient import foundation.e.drive.EdriveApplication import foundation.e.drive.R -import foundation.e.drive.utils.AppConstants -import foundation.e.drive.utils.CommonUtils +import foundation.e.drive.account.AccountUtils import foundation.e.drive.utils.DavClientProvider import timber.log.Timber import java.util.concurrent.Executors @@ -59,7 +57,7 @@ class SyncWorker( override fun doWork(): Result { try { - account = loadAccount() + account = AccountUtils.getAccount(applicationContext) if (account == null) { Timber.d("Warning : account is null") syncManager.startListeningFiles(applicationContext as EdriveApplication) @@ -89,15 +87,6 @@ class SyncWorker( return Result.success() } - private fun loadAccount(): Account? { - val context = applicationContext - val prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) - val accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, "") - val accountType = context.getString(R.string.eelo_account_type) - //for above: AS complaint about accountName as String? while it can't be... - return CommonUtils.getAccount(accountName!!, accountType, AccountManager.get(context)) - } - private fun getOcClient(account: Account): OwnCloudClient? { return DavClientProvider.getInstance().getClientInstance( account, 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 0ecf53c8..5a605ef4 100644 --- a/app/src/main/java/foundation/e/drive/utils/CommonUtils.java +++ b/app/src/main/java/foundation/e/drive/utils/CommonUtils.java @@ -46,25 +46,6 @@ import androidx.annotation.Nullable; */ public abstract class CommonUtils { - /** - * This method retrieve Account corresponding to account's name and type - * - * @param accountName Account Name, shouldn't be null - * @param accountType account type - * @param am Account Manager - * @return Account or null if not found - */ - @Nullable - public static Account getAccount(@NonNull String accountName, @NonNull String accountType, @NonNull AccountManager am) { - Account[] accounts = am.getAccountsByType(accountType); - for (int i = -1, size = accounts.length; ++i < size; ) { - if (accounts[i].name.equals(accountName)) { - return accounts[i]; - } - } - return null; - } - /** * This method retrieve Account corresponding to account's type * @@ -124,7 +105,7 @@ public abstract class CommonUtils { public static boolean isMeteredNetworkAllowed(@NonNull Account account) { return ContentResolver.getSyncAutomatically(account, METERED_NETWORK_ALLOWED_AUTHORITY); } - + /** * Tell if there is internet connection * diff --git a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java index 8c01a51e..755d3c10 100644 --- a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java +++ b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java @@ -39,7 +39,7 @@ import java.util.Calendar; import java.util.Locale; import foundation.e.drive.R; -import foundation.e.drive.utils.AccountUtils; +import foundation.e.drive.account.AccountUtils; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.CommonUtils; import timber.log.Timber; -- GitLab From c490817bafc2cca75b9751e8c989958936a51fb1 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 5 Dec 2023 12:15:07 +0100 Subject: [PATCH 09/20] convert AccountUtils from java to kotlin --- .../e/drive/account/AccountUtils.java | 77 ------------------- .../e/drive/account/AccountUtils.kt | 62 +++++++++++++++ .../account/receivers/AccountAddedReceiver.kt | 2 +- .../account/setup/RootFolderSetupWorker.java | 2 +- .../e/drive/activity/AccountsActivity.java | 2 +- .../e/drive/periodicScan/FullScanWorker.kt | 2 +- 6 files changed, 66 insertions(+), 81 deletions(-) delete mode 100644 app/src/main/java/foundation/e/drive/account/AccountUtils.java create mode 100644 app/src/main/java/foundation/e/drive/account/AccountUtils.kt diff --git a/app/src/main/java/foundation/e/drive/account/AccountUtils.java b/app/src/main/java/foundation/e/drive/account/AccountUtils.java deleted file mode 100644 index 236f70ae..00000000 --- a/app/src/main/java/foundation/e/drive/account/AccountUtils.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright MURENA SAS 2022 - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package foundation.e.drive.account; - -import static foundation.e.drive.utils.AppConstants.ACCOUNT_DATA_GROUPS; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.content.Context; -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.Arrays; -import java.util.Optional; - -import foundation.e.drive.R; -import foundation.e.drive.utils.AppConstants; - -public class AccountUtils { - - @NonNull - public static Optional getPremiumGroup(@NonNull AccountManager accountManager, @Nullable Account account) { - if (account == null) { - return Optional.empty(); - } - - final String groupData = accountManager.getUserData(account, ACCOUNT_DATA_GROUPS); - - if (groupData == null || groupData.isEmpty()) { - return Optional.empty(); - } - - final String[] groups = groupData.split(","); - - return Arrays.stream(groups) - .filter(group -> group.contains("premium-")) - .findFirst(); - } - - public static @Nullable Account getAccount(@NonNull final Context context) { - final SharedPreferences prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE); - final String accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, ""); - - return getAccount(accountName, context); - } - - public static @Nullable Account getAccount(@NonNull final String accountName, @NonNull final Context context) { - if (accountName.isEmpty()) return null; - - final AccountManager accountManager = AccountManager.get(context); - final String accountType = context.getString(R.string.eelo_account_type); - - final Account[] accounts = accountManager.getAccountsByType(accountType); - for (int i = -1, size = accounts.length; ++i < size; ) { - if (accounts[i].name.equals(accountName)) { - return accounts[i]; - } - } - return null; - } -} diff --git a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt new file mode 100644 index 00000000..fae27e1c --- /dev/null +++ b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt @@ -0,0 +1,62 @@ +/* + * Copyright MURENA SAS 2022-2023 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package foundation.e.drive.account + +import android.accounts.Account +import android.accounts.AccountManager +import android.content.Context +import foundation.e.drive.R +import foundation.e.drive.utils.AppConstants +import foundation.e.drive.utils.AppConstants.ACCOUNT_DATA_GROUPS +import java.util.Optional +import java.util.function.Predicate + +object AccountUtils { + + @JvmStatic + fun getPremiumGroup(accountManager: AccountManager, account: Account?): Optional { + if (account == null) return Optional.empty() + + val groupData = accountManager.getUserData(account, ACCOUNT_DATA_GROUPS) + if (groupData.isNullOrEmpty()) return Optional.empty() + + val groups = groupData.split(",") + + return groups.stream() + .filter(Predicate { group: String -> group.contains("premium-")}) + .findFirst() + } + + @JvmStatic + fun getAccount(context: Context): Account? { + val prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) + val accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, "") + + return getAccount(accountName!!, context) + } + + + @JvmStatic + fun getAccount(accountName: String, context: Context): Account? { + if (accountName.isEmpty()) return null + + val accountManager = AccountManager.get(context) + val accountType = context.getString(R.string.eelo_account_type) + + return accountManager.getAccountsByType(accountType) + .firstOrNull { account -> account.name == accountName } + } +} \ No newline at end of file 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 b8d679f9..2d0eb8d9 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 @@ -15,8 +15,8 @@ import android.content.SharedPreferences import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager import foundation.e.drive.R -import foundation.e.drive.models.SyncedFolder import foundation.e.drive.account.AccountUtils +import foundation.e.drive.models.SyncedFolder import foundation.e.drive.utils.AppConstants import foundation.e.drive.utils.DavClientProvider import foundation.e.drive.utils.RootSyncedFolderProvider diff --git a/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java b/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java index 5c03617b..99082e5e 100644 --- a/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java +++ b/app/src/main/java/foundation/e/drive/account/setup/RootFolderSetupWorker.java @@ -23,9 +23,9 @@ import com.owncloud.android.lib.resources.files.CreateFolderRemoteOperation; import java.io.File; +import foundation.e.drive.account.AccountUtils; import foundation.e.drive.database.DbHelper; import foundation.e.drive.models.SyncedFolder; -import foundation.e.drive.account.AccountUtils; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; import timber.log.Timber; diff --git a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java index 7dd2176b..f2bc102a 100644 --- a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java +++ b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java @@ -33,8 +33,8 @@ import com.bumptech.glide.Glide; import com.owncloud.android.lib.common.OwnCloudClient; import foundation.e.drive.R; -import foundation.e.drive.databinding.ActivityAccountsBinding; import foundation.e.drive.account.AccountUtils; +import foundation.e.drive.databinding.ActivityAccountsBinding; import foundation.e.drive.utils.CommonUtils; import foundation.e.drive.utils.DavClientProvider; import foundation.e.drive.widgets.EDriveWidget; 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 e2f21335..855f71ba 100644 --- a/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt +++ b/app/src/main/java/foundation/e/drive/periodicScan/FullScanWorker.kt @@ -15,6 +15,7 @@ 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.account.AccountUtils import foundation.e.drive.database.DbHelper import foundation.e.drive.models.SyncRequest import foundation.e.drive.models.SyncedFolder @@ -23,7 +24,6 @@ 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.account.AccountUtils import foundation.e.drive.utils.AppConstants import foundation.e.drive.utils.AppConstants.KEY_LAST_SCAN_TIME import foundation.e.drive.utils.CommonUtils -- GitLab From 9b1795bd9d5bfba3a63b75c8ef992463b33fec69 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 5 Dec 2023 17:12:27 +0100 Subject: [PATCH 10/20] fix periodic scan worker which doesn't start --- app/src/main/java/foundation/e/drive/work/WorkerUtils.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt b/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt index 56b24fcc..e7850d29 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt +++ b/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt @@ -12,6 +12,7 @@ import androidx.work.ExistingWorkPolicy import androidx.work.WorkManager import foundation.e.drive.account.AccountUserInfoWorker import foundation.e.drive.periodicScan.FullScanWorker +import foundation.e.drive.periodicScan.PeriodicScanWorker import foundation.e.drive.synchronization.SyncWorker import foundation.e.drive.work.WorkRequestFactory.WorkType @@ -31,7 +32,7 @@ object WorkerUtils { @JvmStatic fun enqueuePeriodicFullScan(workManager: WorkManager) { val request = WorkRequestFactory.getPeriodicWorkRequest(WorkType.PERIODIC_SCAN) - workManager.enqueueUniquePeriodicWork(FullScanWorker.UNIQUE_WORK_NAME, + workManager.enqueueUniquePeriodicWork(PeriodicScanWorker.UNIQUE_WORK_NAME, ExistingPeriodicWorkPolicy.KEEP, request) } -- GitLab From 84b122eff5e1984b5f385eee2e92a7d569582964 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 5 Dec 2023 17:37:25 +0100 Subject: [PATCH 11/20] add missing permission to the manifest --- app/src/main/AndroidManifest.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4260d07f..e2caa58f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,11 @@ + + + + Date: Wed, 6 Dec 2023 14:55:06 +0100 Subject: [PATCH 12/20] apply Fahim's suggestion : - AccountUtils.getPremiumGroup() : remove usage of Optional - DebugCmdReceiver: add missing spaces --- .../java/foundation/e/drive/account/AccountUtils.kt | 10 ++++------ .../foundation/e/drive/activity/AccountsActivity.java | 8 +++++--- .../foundation/e/drive/receivers/DebugCmdReceiver.java | 4 ++++ .../java/foundation/e/drive/widgets/EDriveWidget.java | 10 ++++++---- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt index fae27e1c..5a94f541 100644 --- a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt +++ b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt @@ -27,17 +27,15 @@ import java.util.function.Predicate object AccountUtils { @JvmStatic - fun getPremiumGroup(accountManager: AccountManager, account: Account?): Optional { - if (account == null) return Optional.empty() + fun getPremiumGroup(accountManager: AccountManager, account: Account?): String? { + if (account == null) return null val groupData = accountManager.getUserData(account, ACCOUNT_DATA_GROUPS) - if (groupData.isNullOrEmpty()) return Optional.empty() + if (groupData.isNullOrEmpty()) return null val groups = groupData.split(",") - return groups.stream() - .filter(Predicate { group: String -> group.contains("premium-")}) - .findFirst() + return groups.firstOrNull { group: String -> group.contains("premium-") } } @JvmStatic diff --git a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java index f2bc102a..0ed01ebe 100644 --- a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java +++ b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java @@ -113,9 +113,11 @@ public class AccountsActivity extends AppCompatActivity { binding.plan.setText(getString(R.string.free_plan, totalShownQuota)); - AccountUtils.getPremiumGroup(accountManager, account) - .ifPresent(group -> binding.plan.setText(getString(R.string.premium_plan, - group.split("-")[1]))); + final String premiumGroup = AccountUtils.getPremiumGroup(accountManager, account); + if (premiumGroup != null) { + binding.plan.setText(getString(R.string.premium_plan, + premiumGroup.split("-")[1])); + } binding.myPlan.setVisibility(View.VISIBLE); binding.plan.setVisibility(View.VISIBLE); 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 b3ee483b..b62c16d7 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -42,6 +42,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { public static final String ACTION_DUMP_DATABASE = "foundation.e.drive.action.DUMP_DATABASE"; public static final String ACTION_FULL_LOG_ON_PROD = "foundation.e.drive.action.FULL_LOG_ON_PROD"; private static final String FULL_LOG_ENABLE_KEY = "full_log_enable"; + @Override public void onReceive(@NonNull Context context, @NonNull Intent intent) { Timber.tag(DebugCmdReceiver.class.getSimpleName()).v("onReceive"); @@ -84,10 +85,12 @@ public class DebugCmdReceiver extends BroadcastReceiver { final List result = new ArrayList<>(); final int fileAmount = 10; final SyncedFolder parentFolder = DbHelper.getSyncedFolderByLocalPath(dir.getAbsolutePath(), context); + if (parentFolder == null || !parentFolder.isEnabled()) { Timber.d("Won't send sync request: no parent are known for n %s", dir.getAbsolutePath()); return result; } + for (int index = 0; index < fileAmount; index++) { final String fileName = "a"+System.currentTimeMillis()/1200+".txt"; File file = new File(dir.getAbsolutePath(), fileName); @@ -97,6 +100,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { Timber.d("can't create file"); continue; } + final String remotePath = parentFolder.getRemoteFolder()+fileName; final SyncedFileState fileState = new SyncedFileState(-1, fileName, file.getAbsolutePath(), remotePath, "", 0L, parentFolder.getId(), true, 3); diff --git a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java index 755d3c10..f2f39f32 100644 --- a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java +++ b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java @@ -256,10 +256,12 @@ public class EDriveWidget extends AppWidgetProvider { views.setTextViewText(R.id.planName, context.getString(R.string.free_plan, totalShownQuota)); - AccountUtils.getPremiumGroup(accountManager, account) - .ifPresent(group -> views.setTextViewText(R.id.planName, - context.getString(R.string.premium_plan, - group.split("-")[1]))); + final String premiumGroup = AccountUtils.getPremiumGroup(accountManager, account); + if (premiumGroup != null) { + views.setTextViewText(R.id.planName, + context.getString(R.string.premium_plan, + premiumGroup.split("-")[1])); + } views.setTextViewText(R.id.status, context.getString(R.string.progress_status, usedShownQuota, totalShownQuota)); -- GitLab From fd15e2ef1bd38ca19d9dfae6c6a7ab9e0572b106 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 6 Dec 2023 15:25:35 +0100 Subject: [PATCH 13/20] fix eDrive stuck in state: periodic scan --- .../main/java/foundation/e/drive/synchronization/SyncProxy.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt index 3e9a7c00..bd2df430 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProxy.kt @@ -113,11 +113,13 @@ object SyncProxy: SyncRequestCollector, SyncManager { override fun startSynchronization(context: Context) { if (context !is EdriveApplication) { Timber.d("Invalid parameter: startSynchronization(context)") + StateMachine.changeState(SyncState.LISTENING_FILES) return } if (syncRequestQueue.isEmpty()) { Timber.d("Request queue is empty") + StateMachine.changeState(SyncState.LISTENING_FILES) return } -- GitLab From 0e60d10a91ebccf6d37cd52697d701f825977fcb Mon Sep 17 00:00:00 2001 From: Jonathan Klee Date: Thu, 7 Dec 2023 13:39:42 +0100 Subject: [PATCH 14/20] Detekt: Authorize guard clauses returns Fix lint --- app/src/main/java/foundation/e/drive/account/AccountUtils.kt | 2 +- app/src/main/java/foundation/e/drive/work/WorkerUtils.kt | 2 +- detekt.yml | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt index 5a94f541..525724f5 100644 --- a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt +++ b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt @@ -57,4 +57,4 @@ object AccountUtils { return accountManager.getAccountsByType(accountType) .firstOrNull { account -> account.name == accountName } } -} \ No newline at end of file +} diff --git a/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt b/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt index e7850d29..0575de17 100644 --- a/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt +++ b/app/src/main/java/foundation/e/drive/work/WorkerUtils.kt @@ -67,4 +67,4 @@ object WorkerUtils { val request = WorkRequestFactory.getOneTimeWorkRequest(WorkType.ONE_TIME_SYNC, null) workManager.enqueueUniqueWork(SyncWorker.UNIQUE_WORK_NAME, ExistingWorkPolicy.KEEP, request) } -} \ No newline at end of file +} diff --git a/detekt.yml b/detekt.yml index 4efb8651..fb4a8a38 100644 --- a/detekt.yml +++ b/detekt.yml @@ -14,6 +14,9 @@ style: ForbiddenComment: active: false + ReturnCount: + excludeGuardClauses: true + # Complexity rules complexity: -- GitLab From b4931964201419fc8646fd0b801da14ced432762 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 11 Dec 2023 17:37:06 +0100 Subject: [PATCH 15/20] Apply Sayantan's suggestion. add space around '+' and add missing final keyword apply Sayantan's fix on dev_tools.sh: escape ! & \ --- .../java/foundation/e/drive/receivers/DebugCmdReceiver.java | 6 +++--- dev_tools.sh | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) 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 b62c16d7..d1c743c2 100644 --- a/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/DebugCmdReceiver.java @@ -67,7 +67,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { final SyncRequestCollector collector = (SyncRequestCollector) SyncProxy.INSTANCE; collector.onPeriodicScanStart((EdriveApplication) context.getApplicationContext()); - File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); + final File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); final List requests = generateDummyFileToSync(dir, context); if (requests.isEmpty()) return; @@ -92,7 +92,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { } for (int index = 0; index < fileAmount; index++) { - final String fileName = "a"+System.currentTimeMillis()/1200+".txt"; + final String fileName = "a" + System.currentTimeMillis()/1200 + ".txt"; File file = new File(dir.getAbsolutePath(), fileName); try { file.createNewFile(); @@ -101,7 +101,7 @@ public class DebugCmdReceiver extends BroadcastReceiver { continue; } - final String remotePath = parentFolder.getRemoteFolder()+fileName; + final String remotePath = parentFolder.getRemoteFolder() + fileName; final SyncedFileState fileState = new SyncedFileState(-1, fileName, file.getAbsolutePath(), remotePath, "", 0L, parentFolder.getId(), true, 3); final SyncRequest request = new SyncRequest(fileState, SyncRequest.Type.UPLOAD); diff --git a/dev_tools.sh b/dev_tools.sh index 2f7f7a5c..5f7d3e60 100755 --- a/dev_tools.sh +++ b/dev_tools.sh @@ -24,13 +24,13 @@ function printHelp() { function registerAccount() { echo "calling script to add account into device - /!\ Device need to be connecter to WI_FI + /"'!'"\\ Device need to be connecter to WI_FI - /!\ In order to let it work, + /"'!'"\\ In order to let it work, check that credentials & server URL are set in registerAccount2.sh - /i\ please also consider, that the script will need to be updated if UI + /i\\ please also consider, that the script will need to be updated if UI changes "; -- GitLab From 85757b83745f6e59bee52034f4324a392845dbd2 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 11 Dec 2023 18:03:03 +0100 Subject: [PATCH 16/20] refactor AccountUtils.getPremiumGroup() into gretPremiumPlan() factorize code from AccountActivity.java et EdriveWidget Thanks to Sayantan's suggestion split getPremiumPlan() into 3 method to fix linter --- .../e/drive/account/AccountUtils.kt | 29 +++++++++++++------ .../e/drive/activity/AccountsActivity.java | 7 ++--- .../e/drive/widgets/EDriveWidget.java | 7 ++--- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt index 525724f5..b376473e 100644 --- a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt +++ b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt @@ -19,34 +19,45 @@ import android.accounts.Account import android.accounts.AccountManager import android.content.Context import foundation.e.drive.R -import foundation.e.drive.utils.AppConstants +import foundation.e.drive.utils.AppConstants.SHARED_PREFERENCE_NAME import foundation.e.drive.utils.AppConstants.ACCOUNT_DATA_GROUPS -import java.util.Optional -import java.util.function.Predicate object AccountUtils { @JvmStatic - fun getPremiumGroup(accountManager: AccountManager, account: Account?): String? { + fun getPremiumPlan(accountManager: AccountManager, account: Account?): String? { if (account == null) return null - val groupData = accountManager.getUserData(account, ACCOUNT_DATA_GROUPS) + val premiumGroup = extractPremiumGroup(groupData) + return extractPremiumPlan(premiumGroup) + } + + @JvmStatic + private fun extractPremiumPlan(premiumGroup: String?): String? { + if (premiumGroup.isNullOrEmpty()) return null + + val splitPremiumGroup = premiumGroup.split("-") + return if (splitPremiumGroup.size < 2) null + else splitPremiumGroup[1] + } + + @JvmStatic + private fun extractPremiumGroup(groupData: String?): String? { if (groupData.isNullOrEmpty()) return null val groups = groupData.split(",") - - return groups.firstOrNull { group: String -> group.contains("premium-") } + return groups.firstOrNull { group: String -> group.contains("premium-") + } } @JvmStatic fun getAccount(context: Context): Account? { - val prefs = context.getSharedPreferences(AppConstants.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) + val prefs = context.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE) val accountName = prefs.getString(AccountManager.KEY_ACCOUNT_NAME, "") return getAccount(accountName!!, context) } - @JvmStatic fun getAccount(accountName: String, context: Context): Account? { if (accountName.isEmpty()) return null diff --git a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java index 0ed01ebe..a0aea0e5 100644 --- a/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java +++ b/app/src/main/java/foundation/e/drive/activity/AccountsActivity.java @@ -113,10 +113,9 @@ public class AccountsActivity extends AppCompatActivity { binding.plan.setText(getString(R.string.free_plan, totalShownQuota)); - final String premiumGroup = AccountUtils.getPremiumGroup(accountManager, account); - if (premiumGroup != null) { - binding.plan.setText(getString(R.string.premium_plan, - premiumGroup.split("-")[1])); + final String premiumPlan = AccountUtils.getPremiumPlan(accountManager, account); + if (premiumPlan != null) { + binding.plan.setText(getString(R.string.premium_plan, premiumPlan)); } binding.myPlan.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java index f2f39f32..ddc61ff4 100644 --- a/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java +++ b/app/src/main/java/foundation/e/drive/widgets/EDriveWidget.java @@ -256,11 +256,10 @@ public class EDriveWidget extends AppWidgetProvider { views.setTextViewText(R.id.planName, context.getString(R.string.free_plan, totalShownQuota)); - final String premiumGroup = AccountUtils.getPremiumGroup(accountManager, account); - if (premiumGroup != null) { + final String premiumPlan = AccountUtils.getPremiumPlan(accountManager, account); + if (premiumPlan != null) { views.setTextViewText(R.id.planName, - context.getString(R.string.premium_plan, - premiumGroup.split("-")[1])); + context.getString(R.string.premium_plan, premiumPlan)); } views.setTextViewText(R.id.status, context.getString(R.string.progress_status, -- GitLab From 9ce70d326c9b9c303fcbab93d47e6f2c38128a99 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 11 Dec 2023 18:18:25 +0100 Subject: [PATCH 17/20] update BootCompletedReceiver.java: rename updatePreferences() --- .../e/drive/receivers/BootCompletedReceiver.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java index e4c2a919..ae1c037b 100644 --- a/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java +++ b/app/src/main/java/foundation/e/drive/receivers/BootCompletedReceiver.java @@ -50,11 +50,12 @@ public class BootCompletedReceiver extends BroadcastReceiver { if (isOsUpdated(prefs, currentDateProp)) { // App is persistent so can only be updated (by replacement) on OS update handleOsUpdate(context); } + changeSetupCompletedPreferenceKey(prefs); - updatePreferences(prefs); + if (!isSetupCompleted(prefs)) return; final int lastSavedVersionCode = prefs.getInt(PREF_VERSION_CODE, VERSION_CODE_FOR_UPDATE_1); - if (isEdriveUpdated(lastSavedVersionCode) && isSetupCompleted(prefs)) { + if (isEdriveUpdated(lastSavedVersionCode)) { onEdriveUpdate(lastSavedVersionCode, context); prefs.edit().putInt(PREF_VERSION_CODE, BuildConfig.VERSION_CODE).apply(); } @@ -65,10 +66,10 @@ public class BootCompletedReceiver extends BroadcastReceiver { private void forceDBUpdate(@NonNull Context context) { final DbHelper dbHelper = new DbHelper(context); - dbHelper.getWritableDatabase().close(); //Force upgrade of db. + dbHelper.getWritableDatabase().close(); } - private void updatePreferences(@NonNull SharedPreferences prefs) { + private void changeSetupCompletedPreferenceKey(@NonNull SharedPreferences prefs) { if (prefs.getBoolean(OLD_SETUP_COMPLETED_PREF_KEY, false)) { Timber.i("Update setup complete preferences"); prefs -- GitLab From 34b40504db146da952efb54fd81d48c8f5669bdf Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 13 Dec 2023 15:30:52 +0100 Subject: [PATCH 18/20] fix java.lang.RuntimeException: Accessing result data after operation failed --- .../tasks/UploadFileOperation.java | 53 +++++++++++++------ 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java b/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java index e141198c..5d144d21 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java +++ b/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java @@ -99,13 +99,13 @@ public class UploadFileOperation extends RemoteOperation { final ResultCode resultCode; if (uploadResult.isSuccess()) { - updateSyncedFileState(uploadResult, file.lastModified(), client); + final String latestEtag = getLatestEtagAfterUpload(uploadResult, client); + updateSyncedFileState(latestEtag, file.lastModified()); resultCode = uploadResult.getCode(); } else { resultCode = onUploadFailure(uploadResult.getCode(), file.getName()); } - DbHelper.manageSyncedFileStateDB(syncedState, "UPDATE", context); return new RemoteOperationResult(resultCode); } @@ -180,30 +180,49 @@ public class UploadFileOperation extends RemoteOperation { /** * Update syncedFileState (etag & last modified) in case of successful upload - * @param uploadResult The Upload's result instance + * @param latestEtag new eTag of the remoteFile * @param fileLastModified value of local file's last modified - * @param client The client used to check etag if missing */ - private void updateSyncedFileState(final RemoteOperationResult uploadResult, final long fileLastModified, final OwnCloudClient client) { - //The below if statement should only be called for chunked upload. But + private void updateSyncedFileState(@Nullable final String latestEtag, final long fileLastModified) { + if (latestEtag != null) { + syncedState.setLastEtag(latestEtag); + } + + syncedState.setLastModified(fileLastModified); + DbHelper.manageSyncedFileStateDB(syncedState, "UPDATE", context); + } + + private @Nullable String getLatestEtagAfterUpload(@NonNull final RemoteOperationResult uploadResult, @NonNull final OwnCloudClient client) { + + if (uploadResult.getResultData() != null) { + return uploadResult.getResultData(); + } + + //The below code should only be called for chunked upload. But //for some unknown reason, the simple file upload doesn't give the eTag in the result // so, I moved the code here as a security - if (uploadResult.getResultData() == null) { - final RemoteOperationResult result = readRemoteFile(syncedState.getRemotePath(), client); - final ArrayList resultData = result.getData(); - if (result.isSuccess() && resultData != null && !resultData.isEmpty()) { - final String latestETag = ((RemoteFile) resultData.get(0)).getEtag(); - uploadResult.setResultData(latestETag); - } + try { + return readLatestEtagFromCloud(client); + } catch (ClassCastException exception) { + Timber.w("Impossible to read eTag from cloud: %s", exception.getMessage()); + return null; } - final String etag = uploadResult.getResultData(); + } + + private @Nullable String readLatestEtagFromCloud(@NonNull final OwnCloudClient client) throws ClassCastException{ + final RemoteOperationResult result = readRemoteFile(syncedState.getRemotePath(), client); + if (!result.isSuccess()) return null; - if (etag != null) { - syncedState.setLastEtag(etag); + final ArrayList resultData = result.getData(); + + if (resultData == null || resultData.isEmpty()) { + return null; } - syncedState.setLastModified(fileLastModified); + + return ((RemoteFile) resultData.get(0)).getEtag(); } + /** * Perform an operation to check available space on server before to upload * @param client OwnCloudClient -- GitLab From bfeebcbec04d6c8fbdd30e7f9236185eeb4f502b Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Mon, 18 Dec 2023 08:29:51 +0000 Subject: [PATCH 19/20] Apply 2 suggestion(s) to 1 file(s) --- app/src/main/java/foundation/e/drive/account/AccountUtils.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt index b376473e..7d73f23a 100644 --- a/app/src/main/java/foundation/e/drive/account/AccountUtils.kt +++ b/app/src/main/java/foundation/e/drive/account/AccountUtils.kt @@ -13,6 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + package foundation.e.drive.account import android.accounts.Account @@ -46,8 +47,7 @@ object AccountUtils { if (groupData.isNullOrEmpty()) return null val groups = groupData.split(",") - return groups.firstOrNull { group: String -> group.contains("premium-") - } + return groups.firstOrNull { group: String -> group.contains("premium-") } } @JvmStatic -- GitLab From bfd584118564556fd0b2c4f410dbdc0e48e0e60b Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 18 Dec 2023 11:08:32 +0100 Subject: [PATCH 20/20] apply Jonathan's fix --- .../tasks/UploadFileOperation.java | 4 ++-- registerAccount.sh | 19 +++---------------- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java b/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java index 5d144d21..d86508bc 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java +++ b/app/src/main/java/foundation/e/drive/synchronization/tasks/UploadFileOperation.java @@ -99,7 +99,7 @@ public class UploadFileOperation extends RemoteOperation { final ResultCode resultCode; if (uploadResult.isSuccess()) { - final String latestEtag = getLatestEtagAfterUpload(uploadResult, client); + final String latestEtag = getLatestEtag(uploadResult, client); updateSyncedFileState(latestEtag, file.lastModified()); resultCode = uploadResult.getCode(); } else { @@ -192,7 +192,7 @@ public class UploadFileOperation extends RemoteOperation { DbHelper.manageSyncedFileStateDB(syncedState, "UPDATE", context); } - private @Nullable String getLatestEtagAfterUpload(@NonNull final RemoteOperationResult uploadResult, @NonNull final OwnCloudClient client) { + private @Nullable String getLatestEtag(@NonNull final RemoteOperationResult uploadResult, @NonNull final OwnCloudClient client) { if (uploadResult.getResultData() != null) { return uploadResult.getResultData(); diff --git a/registerAccount.sh b/registerAccount.sh index ae8b0cb4..438228d1 100755 --- a/registerAccount.sh +++ b/registerAccount.sh @@ -3,8 +3,9 @@ adb shell am start -a android.settings.ADD_ACCOUNT_SETTINGS sleep 1 -# Select /e/ account as it is the first one in the type list -adb shell input keyevent TAB +# Select /e/ account +# number of input depend on language set on the device + adb shell input keyevent TAB sleep 1 @@ -52,17 +53,3 @@ else adb shell input keyevent TAB adb shell input keyevent ENTER fi - - -## OLD WAY to put server uri - -#Remove server Uri -#adb shell input keyevent KEYCODE_MOVE_END -#adb shell input keyevent --longpress $(printf 'KEYCODE_DEL %.0s' {1..250}) -#Add new server Uri -#adb shell input text $SERVER_URI - -#Validate the form -#sleep 1 -#adb shell input keyevent TAB -#adb shell input keyevent ENTER -- GitLab