From 50a83f1641c90abccd7222971408c99dde25346a Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 18 Dec 2023 18:11:47 +0100 Subject: [PATCH 1/7] introduce SyncProgressNotifier - Extract notification code from SyncWorker into SyncProgressNotifier - Add AtomicInteger into SyncWorker to count pendingRequest - Update AtomicInteger of SyncWorker in SyncTask and use it through SyncProgressNotifier to update notification --- app/src/main/AndroidManifest.xml | 1 + .../synchronization/SyncProgressNotifier.kt | 76 +++++++++++++++++++ .../e/drive/synchronization/SyncTask.kt | 4 + .../e/drive/synchronization/SyncWorker.kt | 56 +++----------- 4 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e2caa58f..b4bdbf18 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ package="foundation.e.drive"> + diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt new file mode 100644 index 00000000..deb17f7b --- /dev/null +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt @@ -0,0 +1,76 @@ +/* + * 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.synchronization + +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.content.Context +import android.content.pm.ServiceInfo +import android.os.Build +import androidx.core.app.NotificationCompat +import androidx.work.ForegroundInfo +import foundation.e.drive.R + +class SyncProgressNotifier(private val context: Context) { + companion object { + const val NOTIFICATION_ID = 2003004 + const val NOTIF_CHANNEL_ID = "syncChannelId" + } + + private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + + fun getNotification(requestCounter: Int): Notification { + val text = getNotificationText(requestCounter) + return buildNotification(text) + } + + fun notifyTaskFinished(requestCounter: Int){ + notificationManager.notify(NOTIFICATION_ID, getNotification(requestCounter)) + } + + fun cancelAllSyncNotifications() { + notificationManager.cancel(NOTIFICATION_ID) + } + + private fun buildNotification(text: String): Notification { + val title = context.getString(R.string.notif_sync_is_running_title) + + return NotificationCompat.Builder(context, NOTIF_CHANNEL_ID) + .setOngoing(true) + .setContentTitle(title) + .setContentText(text) + .setSmallIcon(R.drawable.ic_synchronization) + .build() + } + + private fun getNotificationText(requestCount: Int): String { + return context.resources + .getQuantityString(R.plurals.notif_sync_is_running_txt, requestCount, requestCount) + } + + fun createNotificationChannel() { + val channelName = context.getString(R.string.notif_sync_channel_name) + val importance = NotificationManager.IMPORTANCE_MIN + val channel = NotificationChannel(NOTIF_CHANNEL_ID, channelName, importance) + val channelDescription = context.getString(R.string.notif_sync_channel_description) + channel.description = channelDescription + + notificationManager.createNotificationChannel(channel) + } + + internal fun createForegroundInfo(requestCount: Int): ForegroundInfo { + val notification = getNotification(requestCount) + + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + ForegroundInfo(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC) + } else { + ForegroundInfo(NOTIFICATION_ID, notification) + } + } +} \ No newline at end of file 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 497d547b..b6fb3bd3 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt @@ -8,6 +8,7 @@ package foundation.e.drive.synchronization import android.accounts.Account +import android.app.NotificationManager import android.content.Context import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult @@ -38,6 +39,8 @@ class SyncTask( private val fileName = request.syncedFileState.name private val fileLocalPath = request.syncedFileState.localPath + private val syncNotifier = SyncProgressNotifier(context) + override fun run() { if (!canStart()) { @@ -55,6 +58,7 @@ class SyncTask( DISABLE_SYNCING -> runSyncDisabling() } + syncNotifier.notifyTaskFinished(SyncWorker.pendingTaskCounter.decrementAndGet()) updateFailureCounter(request, succeed) syncManager.removeStartedRequest(fileLocalPath) Timber.d("${request.operationType.name} finished for $fileLocalPath") 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 861d7b7c..c3947667 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncWorker.kt @@ -8,26 +8,19 @@ package foundation.e.drive.synchronization import android.accounts.Account -import android.app.NotificationChannel -import android.app.NotificationManager import android.content.Context -import android.content.Context.NOTIFICATION_SERVICE -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 com.owncloud.android.lib.common.OwnCloudClient import foundation.e.drive.EdriveApplication -import foundation.e.drive.R import foundation.e.drive.account.AccountUtils import foundation.e.drive.utils.DavClientProvider import timber.log.Timber import java.util.concurrent.Executors import java.util.concurrent.Future import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicInteger class SyncWorker( context: Context, @@ -36,20 +29,19 @@ class SyncWorker( companion object { const val UNIQUE_WORK_NAME = "syncWorker" - const val NOTIF_CHANNEL_ID = "syncChannelId" - const val NOTIFICATION_ID = 2003004 + internal lateinit var pendingTaskCounter: AtomicInteger private const val threadAmount = 2 private val syncManager = SyncProxy as SyncManager } private var account: Account? = null private var ocClient: OwnCloudClient? = null - private val notificationManager = applicationContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager private var executor = Executors.newFixedThreadPool(threadAmount) + private val syncNotifier = SyncProgressNotifier(applicationContext) override fun onStopped() { Timber.d("SyncWorker has been stopped") - notificationManager.cancel(NOTIFICATION_ID) + syncNotifier.cancelAllSyncNotifications() executor.shutdownNow() super.onStopped() @@ -70,15 +62,16 @@ class SyncWorker( syncManager.startListeningFiles(applicationContext as EdriveApplication) return Result.failure() } - - createNotificationChannel() + syncNotifier.createNotificationChannel() while (!syncManager.isQueueEmpty()) { - setForegroundAsync(createForegroundInfo()) + val requestCount = syncManager.getQueueSize() + pendingTaskCounter = AtomicInteger(requestCount) + setForegroundAsync(syncNotifier.createForegroundInfo(requestCount)) executeRequests() } - notificationManager.cancel(NOTIFICATION_ID) + syncNotifier.cancelAllSyncNotifications() syncManager.startListeningFiles(applicationContext as EdriveApplication) } catch (exception: Exception) { Timber.w(exception) @@ -120,35 +113,4 @@ class SyncWorker( executor.awaitTermination(30, TimeUnit.SECONDS) } } - - private fun createForegroundInfo(): ForegroundInfo { - val title = applicationContext.getString(R.string.notif_sync_is_running_title) - val requestCount = syncManager.getQueueSize() - val text = applicationContext.resources - .getQuantityString(R.plurals.notif_sync_is_running_txt, requestCount, requestCount) - - val notification = NotificationCompat.Builder(applicationContext, NOTIF_CHANNEL_ID) - .setOngoing(true) - .setContentTitle(title) - .setContentText(text) - .setSmallIcon(R.drawable.ic_synchronization) - - .build() - - 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() { - val channelName = applicationContext.getString(R.string.notif_sync_channel_name) - val importance = NotificationManager.IMPORTANCE_MIN - val channel = NotificationChannel(NOTIF_CHANNEL_ID, channelName, importance) - val channelDescription = applicationContext.getString(R.string.notif_sync_channel_description) - channel.description = channelDescription - - notificationManager.createNotificationChannel(channel) - } } \ No newline at end of file -- GitLab From b47aa4b053d67e0e8ab37297a8f4e9ce2a6480b2 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Mon, 18 Dec 2023 18:16:39 +0100 Subject: [PATCH 2/7] Fix build issue --- .../drive/account/receivers/AccountRemoveCallbackReceiver.java | 3 ++- .../foundation/e/drive/synchronization/SyncProgressNotifier.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java b/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java index 668fb93d..23f8d392 100644 --- a/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java +++ b/app/src/main/java/foundation/e/drive/account/receivers/AccountRemoveCallbackReceiver.java @@ -29,6 +29,7 @@ import foundation.e.drive.EdriveApplication; import foundation.e.drive.R; import foundation.e.drive.database.DbHelper; import foundation.e.drive.database.FailedSyncPrefsManager; +import foundation.e.drive.synchronization.SyncProgressNotifier; import foundation.e.drive.synchronization.SyncWorker; import foundation.e.drive.utils.AppConstants; import foundation.e.drive.utils.DavClientProvider; @@ -153,7 +154,7 @@ public class AccountRemoveCallbackReceiver extends BroadcastReceiver { notificationManager.cancelAll(); try { notificationManager.deleteNotificationChannel(AppConstants.notificationChannelID); - notificationManager.deleteNotificationChannel(SyncWorker.NOTIF_CHANNEL_ID); + notificationManager.deleteNotificationChannel(SyncProgressNotifier.NOTIF_CHANNEL_ID); } catch (Exception exception) { Timber.e(exception, "Cannot delete notification Channel"); } diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt index deb17f7b..459dc00e 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt @@ -73,4 +73,4 @@ class SyncProgressNotifier(private val context: Context) { ForegroundInfo(NOTIFICATION_ID, notification) } } -} \ No newline at end of file +} -- GitLab From b8711106e8c1d6050c9e14df21934bb9657dd445 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 19 Dec 2023 11:41:45 +0100 Subject: [PATCH 3/7] remove useless function --- .../synchronization/SyncProgressNotifier.kt | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt index 459dc00e..a8f7bfd7 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt @@ -25,20 +25,8 @@ class SyncProgressNotifier(private val context: Context) { private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - fun getNotification(requestCounter: Int): Notification { + private fun createNotification(requestCounter: Int): Notification { val text = getNotificationText(requestCounter) - return buildNotification(text) - } - - fun notifyTaskFinished(requestCounter: Int){ - notificationManager.notify(NOTIFICATION_ID, getNotification(requestCounter)) - } - - fun cancelAllSyncNotifications() { - notificationManager.cancel(NOTIFICATION_ID) - } - - private fun buildNotification(text: String): Notification { val title = context.getString(R.string.notif_sync_is_running_title) return NotificationCompat.Builder(context, NOTIF_CHANNEL_ID) @@ -49,6 +37,14 @@ class SyncProgressNotifier(private val context: Context) { .build() } + fun notifyTaskFinished(requestCounter: Int) { + notificationManager.notify(NOTIFICATION_ID, createNotification(requestCounter)) + } + + fun cancelAllSyncNotifications() { + notificationManager.cancel(NOTIFICATION_ID) + } + private fun getNotificationText(requestCount: Int): String { return context.resources .getQuantityString(R.plurals.notif_sync_is_running_txt, requestCount, requestCount) @@ -65,7 +61,7 @@ class SyncProgressNotifier(private val context: Context) { } internal fun createForegroundInfo(requestCount: Int): ForegroundInfo { - val notification = getNotification(requestCount) + val notification = createNotification(requestCount) return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { ForegroundInfo(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC) -- GitLab From 28a27d168c8ce50e53ce3e586fa1d3c728cd8fb0 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 19 Dec 2023 11:45:13 +0100 Subject: [PATCH 4/7] fix indentation in SyncProgressNotifier --- .../e/drive/synchronization/SyncProgressNotifier.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt index a8f7bfd7..3d0a259f 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt @@ -50,7 +50,7 @@ class SyncProgressNotifier(private val context: Context) { .getQuantityString(R.plurals.notif_sync_is_running_txt, requestCount, requestCount) } - fun createNotificationChannel() { + fun createNotificationChannel() { val channelName = context.getString(R.string.notif_sync_channel_name) val importance = NotificationManager.IMPORTANCE_MIN val channel = NotificationChannel(NOTIF_CHANNEL_ID, channelName, importance) @@ -60,7 +60,7 @@ class SyncProgressNotifier(private val context: Context) { notificationManager.createNotificationChannel(channel) } - internal fun createForegroundInfo(requestCount: Int): ForegroundInfo { + internal fun createForegroundInfo(requestCount: Int): ForegroundInfo { val notification = createNotification(requestCount) return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { -- GitLab From 9ceec36de37525e2271dbb9c75ac5a11ca2ecdc3 Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Tue, 19 Dec 2023 14:48:30 +0100 Subject: [PATCH 5/7] Remove useless import from SyncTask.kt --- app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt | 1 - 1 file changed, 1 deletion(-) 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 b6fb3bd3..7a43489f 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncTask.kt @@ -8,7 +8,6 @@ package foundation.e.drive.synchronization import android.accounts.Account -import android.app.NotificationManager import android.content.Context import com.owncloud.android.lib.common.OwnCloudClient import com.owncloud.android.lib.common.operations.RemoteOperationResult -- GitLab From 1238c1ce87d230f7cd669eabb66c789a4470ae29 Mon Sep 17 00:00:00 2001 From: Hasib Prince Date: Wed, 20 Dec 2023 08:31:53 +0000 Subject: [PATCH 6/7] Apply 1 suggestion(s) to 1 file(s) --- .../foundation/e/drive/synchronization/SyncProgressNotifier.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt index 3d0a259f..79772ea3 100644 --- a/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt +++ b/app/src/main/java/foundation/e/drive/synchronization/SyncProgressNotifier.kt @@ -5,6 +5,7 @@ * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html */ + package foundation.e.drive.synchronization import android.app.Notification -- GitLab From 11e8b9bea27c1ba434e8732a1e30576fdfaa74ce Mon Sep 17 00:00:00 2001 From: vincent Bourgmayer Date: Wed, 20 Dec 2023 10:23:39 +0100 Subject: [PATCH 7/7] change notification's title --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fda41306..1ebbd1a2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,7 +31,7 @@ 99% of your allotted cloud storage is used. Please take action. You\'ve filled your allotted cloud storage up to 90%. You\'ve filled your allotted cloud storage up to 80%. - File synchronization in progress + File synchronization %d file to sync %d files to sync -- GitLab