From 3f79f149c8bc7891ea2c272c619c45deb7356a98 Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Thu, 14 Dec 2023 10:55:28 +0100 Subject: [PATCH 1/6] Add space for background worker execution info in ETM Activity Signed-off-by: Jonas Mayer --- .../etm/pages/EtmBackgroundJobsFragment.kt | 26 +++++++++++- .../client/jobs/BackgroundJobManagerImpl.kt | 31 +++++++++++++- .../java/com/nextcloud/client/jobs/JobInfo.kt | 13 +++++- .../client/preferences/AppPreferences.java | 9 ++++ .../preferences/AppPreferencesImpl.java | 21 ++++++++++ .../layout/etm_background_job_list_item.xml | 41 +++++++++++++++++++ app/src/main/res/values/strings.xml | 2 + 7 files changed, 140 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt index 714c018e5942..dbbf555a5b9f 100644 --- a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt +++ b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt @@ -50,6 +50,9 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { val started = view.findViewById(R.id.etm_background_job_started) val progress = view.findViewById(R.id.etm_background_job_progress) private val progressRow = view.findViewById(R.id.etm_background_job_progress_row) + val executionCount = view.findViewById(R.id.etm_background_execution_count) + val executionLog = view.findViewById(R.id.etm_background_execution_logs) + private val executionLogRow = view.findViewById(R.id.etm_background_execution_logs_row) var progressEnabled: Boolean = progressRow.visibility == View.VISIBLE get() { @@ -63,6 +66,20 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { View.GONE } } + + var logsEnabled: Boolean = executionLogRow.visibility == View.VISIBLE + get() { + return executionLogRow.visibility == View.VISIBLE + } + set(value) { + field = value + executionLogRow.visibility = if (value) { + View.VISIBLE + } else { + View.GONE + } + } + } private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:MM:ssZ", Locale.getDefault()) @@ -74,7 +91,12 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = inflater.inflate(R.layout.etm_background_job_list_item, parent, false) - return ViewHolder(view) + val viewHolder = ViewHolder(view) + viewHolder.logsEnabled = false + view.setOnClickListener { + viewHolder.logsEnabled = !viewHolder.logsEnabled + } + return viewHolder } override fun getItemCount(): Int { @@ -94,6 +116,8 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { } else { vh.progressEnabled = false } + vh.executionCount.text = "0" + vh.executionLog.text = "None" } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt index 7e954a0b29db..f5449fa1208e 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt @@ -37,10 +37,13 @@ import androidx.work.workDataOf import com.nextcloud.client.account.User import com.nextcloud.client.core.Clock import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork +import com.nextcloud.client.preferences.AppPreferences import com.owncloud.android.datamodel.OCFile +import java.time.LocalDate import java.util.Date import java.util.UUID import java.util.concurrent.TimeUnit +import javax.inject.Inject import kotlin.reflect.KClass /** @@ -63,7 +66,11 @@ internal class BackgroundJobManagerImpl( private val clock: Clock ) : BackgroundJobManager { + @Inject + private var preferences: AppPreferences? = null + companion object { + const val TAG_ALL = "*" // This tag allows us to retrieve list of all jobs run by Nextcloud client const val JOB_CONTENT_OBSERVER = "content_observer" const val JOB_PERIODIC_CONTACTS_BACKUP = "periodic_contacts_backup" @@ -98,6 +105,8 @@ internal class BackgroundJobManagerImpl( const val DEFAULT_PERIODIC_JOB_INTERVAL_MINUTES = 15L const val DEFAULT_IMMEDIATE_JOB_DELAY_SEC = 3L + private const val KEEP_LOG_MILLIS = 1000 * 60 * 60 * 24 *3L + fun formatNameTag(name: String, user: User? = null): String { return if (user == null) { "$TAG_PREFIX_NAME:$name" @@ -143,14 +152,34 @@ internal class BackgroundJobManagerImpl( name = metadata.get(TAG_PREFIX_NAME) ?: NOT_SET_VALUE, user = metadata.get(TAG_PREFIX_USER) ?: NOT_SET_VALUE, started = timestamp, - progress = info.progress.getInt("progress", -1) + progress = info.progress.getInt("progress", -1), ) } else { null } } + + fun deleteOldLogs(logEntries: MutableList) : MutableList{ + + logEntries.removeIf { + return@removeIf it.started != null && + Date(Date().time - KEEP_LOG_MILLIS).before(it.started) + } + return logEntries + + } + + } + fun logStartOfWorker(workerName : String){ + if (preferences == null) return; + + preferences!!.readLogEntry() + } + + fun logEndOfWorker(workerName: String) + /** * Create [OneTimeWorkRequest.Builder] pre-set with common attributes */ diff --git a/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt b/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt index 4a1de45f5644..eae4c7476b93 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt @@ -19,6 +19,8 @@ */ package com.nextcloud.client.jobs +import androidx.work.ListenableWorker +import com.google.common.util.concurrent.ListenableFuture import java.util.Date import java.util.UUID @@ -28,5 +30,14 @@ data class JobInfo( val name: String = "", val user: String = "", val started: Date = Date(0), - val progress: Int = 0 + val progress: Int = 0, + val executionLog: MutableList? = null +) + + +data class LogEntry ( + val started: Date? = null, + val finished: Date? = null, + val result: String? = null, + var worker: String = "None" ) diff --git a/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java b/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java index 57314e9a9c5f..bb93d3fa5ec8 100644 --- a/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java +++ b/app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java @@ -23,9 +23,12 @@ package com.nextcloud.client.preferences; import com.nextcloud.appReview.AppReviewShownModel; +import com.nextcloud.client.jobs.LogEntry; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.utils.FileSortOrder; +import java.util.List; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -317,6 +320,12 @@ default void onDarkThemeModeChanged(DarkMode mode) { */ int getLastSeenVersionCode(); + void saveLogEntry(List logEntryList); + + List readLogEntry(); + + + /** * Saves the version code as the last seen version code. * diff --git a/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java b/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java index 3e0ea437fbfa..592311c3a096 100644 --- a/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java +++ b/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java @@ -28,11 +28,13 @@ import android.content.SharedPreferences; import android.content.res.Configuration; +import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.nextcloud.appReview.AppReviewShownModel; import com.nextcloud.client.account.User; import com.nextcloud.client.account.UserAccountManager; import com.nextcloud.client.account.UserAccountManagerImpl; +import com.nextcloud.client.jobs.LogEntry; import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.ArbitraryDataProviderImpl; import com.owncloud.android.datamodel.FileDataStorageManager; @@ -41,6 +43,8 @@ import com.owncloud.android.ui.activity.SettingsActivity; import com.owncloud.android.utils.FileSortOrder; +import java.lang.reflect.Type; +import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -108,6 +112,8 @@ public final class AppPreferencesImpl implements AppPreferences { private static final String PREF__STORAGE_PERMISSION_REQUESTED = "storage_permission_requested"; private static final String PREF__IN_APP_REVIEW_DATA = "in_app_review_data"; + private static final String LOG_ENTRY = "log_entry"; + private final Context context; private final SharedPreferences preferences; private final UserAccountManager userAccountManager; @@ -499,6 +505,21 @@ public int getLastSeenVersionCode() { return preferences.getInt(AUTO_PREF__LAST_SEEN_VERSION_CODE, 0); } + @Override + public void saveLogEntry(List logEntryList) { + Gson gson = new Gson(); + String json = gson.toJson(logEntryList); + preferences.edit().putString(LOG_ENTRY, json).apply(); + } + + @Override + public List readLogEntry() { + String json = preferences.getString(LOG_ENTRY, null); + Gson gson = new Gson(); + Type listType = new TypeToken>() {}.getType(); + return gson.fromJson(json, listType); + } + @Override public void setLastSeenVersionCode(int versionCode) { preferences.edit().putInt(AUTO_PREF__LAST_SEEN_VERSION_CODE, versionCode).apply(); diff --git a/app/src/main/res/layout/etm_background_job_list_item.xml b/app/src/main/res/layout/etm_background_job_list_item.xml index 1cd78552ebb0..5ee0b62a173f 100644 --- a/app/src/main/res/layout/etm_background_job_list_item.xml +++ b/app/src/main/res/layout/etm_background_job_list_item.xml @@ -136,4 +136,45 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce27d03b87a0..46d7fa4513d6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -880,6 +880,8 @@ State Started Progress + Times run in 48h + Execution logs Migrations (app upgrade) File transfer Remote path From 5cc6322725440d0b79d103f6757e877a5649c86b Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Tue, 19 Dec 2023 12:56:57 +0100 Subject: [PATCH 2/6] Add logic for logging start and end of important workers Signed-off-by: Jonas Mayer --- .../nextcloud/client/di/ComponentsModule.java | 12 +++++ .../etm/pages/EtmBackgroundJobsFragment.kt | 45 ++++++++++++++++-- .../client/jobs/BackgroundJobFactory.kt | 32 +++++++++---- .../client/jobs/BackgroundJobManager.kt | 5 ++ .../client/jobs/BackgroundJobManagerImpl.kt | 47 ++++++++++++++----- .../client/jobs/ContentObserverWork.kt | 11 ++++- .../nextcloud/client/jobs/FilesSyncWork.kt | 13 +++-- .../client/jobs/FilesUploadWorker.kt | 12 ++++- .../nextcloud/client/jobs/HealthStatusWork.kt | 9 +++- .../java/com/nextcloud/client/jobs/JobInfo.kt | 4 +- .../com/nextcloud/client/jobs/JobsModule.kt | 5 +- .../java/com/nextcloud/client/jobs/TestJob.kt | 10 +++- .../preferences/AppPreferencesImpl.java | 2 + .../layout/etm_background_job_list_item.xml | 35 +++++++------- app/src/main/res/values/strings.xml | 2 +- 15 files changed, 185 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java index 82f9c8738108..83924bdb8f26 100644 --- a/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java +++ b/app/src/main/java/com/nextcloud/client/di/ComponentsModule.java @@ -23,8 +23,11 @@ import com.nextcloud.client.documentscan.DocumentScanActivity; import com.nextcloud.client.editimage.EditImageActivity; import com.nextcloud.client.etm.EtmActivity; +import com.nextcloud.client.etm.pages.EtmBackgroundJobsFragment; import com.nextcloud.client.files.downloader.FileTransferService; +import com.nextcloud.client.jobs.BackgroundJobManagerImpl; import com.nextcloud.client.jobs.NotificationWork; +import com.nextcloud.client.jobs.TestJob; import com.nextcloud.client.logger.ui.LogsActivity; import com.nextcloud.client.logger.ui.LogsViewModel; import com.nextcloud.client.media.PlayerService; @@ -478,4 +481,13 @@ abstract class ComponentsModule { @ContributesAndroidInjector abstract ImageDetailFragment imageDetailFragment(); + + @ContributesAndroidInjector + abstract EtmBackgroundJobsFragment etmBackgroundJobsFragment(); + + @ContributesAndroidInjector + abstract BackgroundJobManagerImpl backgroundJobManagerImpl(); + + @ContributesAndroidInjector + abstract TestJob testJob(); } diff --git a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt index dbbf555a5b9f..2da0f79d4a8e 100644 --- a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt +++ b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt @@ -20,6 +20,7 @@ */ package com.nextcloud.client.etm.pages +import android.annotation.SuppressLint import android.os.Bundle import android.view.LayoutInflater import android.view.Menu @@ -32,15 +33,22 @@ import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.nextcloud.client.di.Injectable import com.nextcloud.client.etm.EtmBaseFragment +import com.nextcloud.client.jobs.BackgroundJobManagerImpl import com.nextcloud.client.jobs.JobInfo +import com.nextcloud.client.preferences.AppPreferences import com.owncloud.android.R import java.text.SimpleDateFormat import java.util.Locale +import javax.inject.Inject -class EtmBackgroundJobsFragment : EtmBaseFragment() { +class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable { - class Adapter(private val inflater: LayoutInflater) : RecyclerView.Adapter() { + @Inject + lateinit var preferences : AppPreferences + + class Adapter(private val inflater: LayoutInflater, private val preferences: AppPreferences) : RecyclerView.Adapter(){ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val uuid = view.findViewById(R.id.etm_background_job_uuid) @@ -53,6 +61,7 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { val executionCount = view.findViewById(R.id.etm_background_execution_count) val executionLog = view.findViewById(R.id.etm_background_execution_logs) private val executionLogRow = view.findViewById(R.id.etm_background_execution_logs_row) + val executionTimesRow = view.findViewById(R.id.etm_background_execution_times_row) var progressEnabled: Boolean = progressRow.visibility == View.VISIBLE get() { @@ -93,6 +102,7 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { val view = inflater.inflate(R.layout.etm_background_job_list_item, parent, false) val viewHolder = ViewHolder(view) viewHolder.logsEnabled = false + viewHolder.executionTimesRow.visibility = View.GONE view.setOnClickListener { viewHolder.logsEnabled = !viewHolder.logsEnabled } @@ -103,6 +113,7 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { return backgroundJobs.size } + @SuppressLint("SetTextI18n") override fun onBindViewHolder(vh: ViewHolder, position: Int) { val info = backgroundJobs[position] vh.uuid.text = info.id.toString() @@ -116,8 +127,32 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { } else { vh.progressEnabled = false } - vh.executionCount.text = "0" - vh.executionLog.text = "None" + + val logs = preferences.readLogEntry() + val logsForThisWorker = logs.filter { BackgroundJobManagerImpl.parseTag(it.workerClass)?.second == info.workerClass } + if(logsForThisWorker.isNotEmpty()) { + vh.executionTimesRow.visibility = View.VISIBLE + vh.executionCount.text = logsForThisWorker.filter { it.started != null }.size.toString() + " (${logsForThisWorker.filter { it.finished != null }.size})" + var logText = "Worker Logs\n\n" + + "*** Does NOT differentiate between imitate or periodic kinds of Work! ***\n"+ + "*** Times run in 48h: Times started (Times finished) ***\n" + logsForThisWorker.forEach{ + logText += "----------------------\n" + logText += "Worker ${BackgroundJobManagerImpl.parseTag(it.workerClass)?.second}\n" + logText += if (it.started == null){ + "ENDED at\n${it.finished}\nWith result: ${it.result}\n" + }else{ + "STARTED at\n${it.started}\n" + } + } + vh.executionLog.text = logText + }else{ + vh.executionLog.text = "Worker Logs\n\n" + + "No Entries -> Maybe logging is not implemented for Worker or it has not run yet." + vh.executionCount.text = "0" + vh.executionTimesRow.visibility = View.GONE + } + } } @@ -131,7 +166,7 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflater.inflate(R.layout.fragment_etm_background_jobs, container, false) - adapter = Adapter(inflater) + adapter = Adapter(inflater, preferences) list = view.findViewById(R.id.etm_background_jobs_list) list.layoutManager = LinearLayoutManager(context) list.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt index 1fb333f5ce37..f126f869e1e9 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt @@ -104,6 +104,7 @@ class BackgroundJobFactory @Inject constructor( FilesUploadWorker::class -> createFilesUploadWorker(context, workerParameters) GeneratePdfFromImagesWork::class -> createPDFGenerateWork(context, workerParameters) HealthStatusWork::class -> createHealthStatusWork(context, workerParameters) + TestJob::class -> createTestJob(context, workerParameters) else -> null // caller falls back to default factory } } @@ -142,7 +143,7 @@ class BackgroundJobFactory @Inject constructor( resources, arbitraryDataProvider, contentResolver, - accountManager + accountManager, ) } @@ -151,7 +152,7 @@ class BackgroundJobFactory @Inject constructor( context, params, logger, - contentResolver + contentResolver, ) } @@ -161,7 +162,7 @@ class BackgroundJobFactory @Inject constructor( params, contentResolver, accountManager, - preferences + preferences, ) } @@ -170,7 +171,7 @@ class BackgroundJobFactory @Inject constructor( context, params, logger, - contentResolver + contentResolver, ) } @@ -183,7 +184,8 @@ class BackgroundJobFactory @Inject constructor( uploadsStorageManager = uploadsStorageManager, connectivityService = connectivityService, powerManagementService = powerManagementService, - syncedFolderProvider = syncedFolderProvider + syncedFolderProvider = syncedFolderProvider, + backgroundJobManager = backgroundJobManager.get() ) } @@ -208,7 +210,7 @@ class BackgroundJobFactory @Inject constructor( preferences, clock, viewThemeUtils.get(), - syncedFolderProvider + syncedFolderProvider, ) } @@ -219,7 +221,7 @@ class BackgroundJobFactory @Inject constructor( notificationManager, accountManager, deckApi, - viewThemeUtils.get() + viewThemeUtils.get(), ) } @@ -245,8 +247,9 @@ class BackgroundJobFactory @Inject constructor( accountManager, viewThemeUtils.get(), localBroadcastManager.get(), + backgroundJobManager.get(), context, - params + params, ) } @@ -258,7 +261,7 @@ class BackgroundJobFactory @Inject constructor( notificationManager = notificationManager, userAccountManager = accountManager, logger = logger, - params = params + params = params, ) } @@ -267,7 +270,16 @@ class BackgroundJobFactory @Inject constructor( context, params, accountManager, - arbitraryDataProvider + arbitraryDataProvider, + backgroundJobManager.get() + ) + } + + private fun createTestJob(context: Context, params: WorkerParameters): TestJob { + return TestJob( + context, + params, + backgroundJobManager.get() ) } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt index cc8bc6a52f69..4fa8a68b2e44 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt @@ -20,6 +20,7 @@ package com.nextcloud.client.jobs import androidx.lifecycle.LiveData +import androidx.work.ListenableWorker import com.nextcloud.client.account.User import com.owncloud.android.datamodel.OCFile @@ -35,6 +36,10 @@ interface BackgroundJobManager { */ val jobs: LiveData> + fun logStartOfWorker(workerName : String?) + + fun logEndOfWorker(workerName: String?, result: ListenableWorker.Result) + /** * Start content observer job that monitors changes in media folders * and launches synchronization when needed. diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt index f5449fa1208e..53a787928f65 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt @@ -36,14 +36,13 @@ import androidx.work.WorkManager import androidx.work.workDataOf import com.nextcloud.client.account.User import com.nextcloud.client.core.Clock +import com.nextcloud.client.di.Injectable import com.nextcloud.client.documentscan.GeneratePdfFromImagesWork import com.nextcloud.client.preferences.AppPreferences import com.owncloud.android.datamodel.OCFile -import java.time.LocalDate import java.util.Date import java.util.UUID import java.util.concurrent.TimeUnit -import javax.inject.Inject import kotlin.reflect.KClass /** @@ -63,11 +62,10 @@ import kotlin.reflect.KClass @Suppress("TooManyFunctions") // we expect this implementation to have rich API internal class BackgroundJobManagerImpl( private val workManager: WorkManager, - private val clock: Clock -) : BackgroundJobManager { + private val clock: Clock, + private val preferences: AppPreferences +) : BackgroundJobManager, Injectable { - @Inject - private var preferences: AppPreferences? = null companion object { @@ -89,6 +87,7 @@ internal class BackgroundJobManagerImpl( const val JOB_PDF_GENERATION = "pdf_generation" const val JOB_IMMEDIATE_CALENDAR_BACKUP = "immediate_calendar_backup" const val JOB_IMMEDIATE_FILES_EXPORT = "immediate_files_export" + const val JOB_PERIODIC_HEALTH_STATUS = "periodic_health_status" const val JOB_IMMEDIATE_HEALTH_STATUS = "immediate_health_status" @@ -98,8 +97,9 @@ internal class BackgroundJobManagerImpl( const val TAG_PREFIX_NAME = "name" const val TAG_PREFIX_USER = "user" + const val TAG_PREFIX_CLASS = "class" const val TAG_PREFIX_START_TIMESTAMP = "timestamp" - val PREFIXES = setOf(TAG_PREFIX_NAME, TAG_PREFIX_USER, TAG_PREFIX_START_TIMESTAMP) + val PREFIXES = setOf(TAG_PREFIX_NAME, TAG_PREFIX_USER, TAG_PREFIX_START_TIMESTAMP, TAG_PREFIX_CLASS) const val NOT_SET_VALUE = "not set" const val PERIODIC_BACKUP_INTERVAL_MINUTES = 24 * 60L const val DEFAULT_PERIODIC_JOB_INTERVAL_MINUTES = 15L @@ -116,6 +116,7 @@ internal class BackgroundJobManagerImpl( } fun formatUserTag(user: User): String = "$TAG_PREFIX_USER:${user.accountName}" + fun formatClassTag(jobClass: KClass): String = "$TAG_PREFIX_CLASS:${jobClass.simpleName}" fun formatTimeTag(startTimestamp: Long): String = "$TAG_PREFIX_START_TIMESTAMP:$startTimestamp" fun parseTag(tag: String): Pair? { @@ -153,6 +154,7 @@ internal class BackgroundJobManagerImpl( user = metadata.get(TAG_PREFIX_USER) ?: NOT_SET_VALUE, started = timestamp, progress = info.progress.getInt("progress", -1), + workerClass = metadata.get(TAG_PREFIX_CLASS) ?: NOT_SET_VALUE ) } else { null @@ -162,8 +164,11 @@ internal class BackgroundJobManagerImpl( fun deleteOldLogs(logEntries: MutableList) : MutableList{ logEntries.removeIf { - return@removeIf it.started != null && - Date(Date().time - KEEP_LOG_MILLIS).before(it.started) + return@removeIf (it.started != null && + Date(Date().time - KEEP_LOG_MILLIS).after(it.started)) || + (it.finished != null && + Date(Date().time - KEEP_LOG_MILLIS).after(it.finished)) + } return logEntries @@ -172,13 +177,27 @@ internal class BackgroundJobManagerImpl( } - fun logStartOfWorker(workerName : String){ - if (preferences == null) return; + override fun logStartOfWorker(workerName : String?) { + val logs = deleteOldLogs(preferences.readLogEntry().toMutableList()) - preferences!!.readLogEntry() + if (workerName == null) { + logs.add(LogEntry(Date(), null, null, NOT_SET_VALUE)) + }else{ + logs.add(LogEntry(Date(), null, null, workerName)) + } + preferences.saveLogEntry(logs) } - fun logEndOfWorker(workerName: String) + override fun logEndOfWorker(workerName: String?, result: ListenableWorker.Result){ + + val logs = deleteOldLogs(preferences.readLogEntry().toMutableList()) + if (workerName == null) { + logs.add(LogEntry(null,Date(),result.toString(), NOT_SET_VALUE)) + }else{ + logs.add(LogEntry(null,Date(),result.toString(),workerName)) + } + preferences.saveLogEntry(logs) + } /** * Create [OneTimeWorkRequest.Builder] pre-set with common attributes @@ -192,6 +211,7 @@ internal class BackgroundJobManagerImpl( .addTag(TAG_ALL) .addTag(formatNameTag(jobName, user)) .addTag(formatTimeTag(clock.currentTime)) + .addTag(formatClassTag(jobClass)) user?.let { builder.addTag(formatUserTag(it)) } return builder } @@ -216,6 +236,7 @@ internal class BackgroundJobManagerImpl( .addTag(TAG_ALL) .addTag(formatNameTag(jobName, user)) .addTag(formatTimeTag(clock.currentTime)) + .addTag(formatClassTag(jobClass)) user?.let { builder.addTag(formatUserTag(it)) } return builder } diff --git a/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt b/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt index 2cab7d17b387..99117678a833 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt @@ -41,12 +41,17 @@ class ContentObserverWork( ) : Worker(appContext, params) { override fun doWork(): Result { + backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) + if (params.triggeredContentUris.size > 0) { checkAndStartFileSyncJob() backgroundJobManager.startMediaFoldersDetectionJob() } recheduleSelf() - return Result.success() + + val result = Result.success() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result } private fun recheduleSelf() { @@ -59,4 +64,8 @@ class ContentObserverWork( backgroundJobManager.startImmediateFilesSyncJob(true, false) } } + + companion object { + val TAG: String = ContentObserverWork::class.java.simpleName + } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt b/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt index cc503a2ad14d..1246b0a333ff 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt @@ -64,7 +64,8 @@ class FilesSyncWork( private val uploadsStorageManager: UploadsStorageManager, private val connectivityService: ConnectivityService, private val powerManagementService: PowerManagementService, - private val syncedFolderProvider: SyncedFolderProvider + private val syncedFolderProvider: SyncedFolderProvider, + private val backgroundJobManager: BackgroundJobManager ) : Worker(context, params) { companion object { @@ -74,10 +75,14 @@ class FilesSyncWork( } override fun doWork(): Result { + backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) + val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false) // If we are in power save mode, better to postpone upload if (powerManagementService.isPowerSavingEnabled && !overridePowerSaving) { - return Result.success() + val result = Result.success() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result } val resources = context.resources val lightVersion = resources.getBoolean(R.bool.syncedFolder_light) @@ -107,7 +112,9 @@ class FilesSyncWork( ) } } - return Result.success() + val result = Result.success() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result } @Suppress("LongMethod") // legacy code diff --git a/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt index 8ddc420e4d12..2563b943667a 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt @@ -69,6 +69,7 @@ class FilesUploadWorker( val userAccountManager: UserAccountManager, val viewThemeUtils: ViewThemeUtils, val localBroadcastManager: LocalBroadcastManager, + private val backgroundJobManager: BackgroundJobManager, val context: Context, params: WorkerParameters ) : Worker(context, params), OnDatatransferProgressListener { @@ -80,10 +81,15 @@ class FilesUploadWorker( private val fileUploaderDelegate = FileUploaderDelegate() override fun doWork(): Result { + backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) + val accountName = inputData.getString(ACCOUNT) if (accountName.isNullOrEmpty()) { Log_OC.w(TAG, "User was null for file upload worker") - return Result.failure() // user account is needed + + val result = Result.failure() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result // user account is needed } /* @@ -100,7 +106,9 @@ class FilesUploadWorker( } Log_OC.d(TAG, "No more pending uploads for account $accountName, stopping work") - return Result.success() + val result = Result.success() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result // user account is needed } private fun handlePendingUploads(uploads: List, accountName: String) { diff --git a/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt b/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt index ba2945dc71f3..2512f42e706d 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt @@ -42,9 +42,12 @@ class HealthStatusWork( private val context: Context, params: WorkerParameters, private val userAccountManager: UserAccountManager, - private val arbitraryDataProvider: ArbitraryDataProvider + private val arbitraryDataProvider: ArbitraryDataProvider, + private val backgroundJobManager: BackgroundJobManager ) : Worker(context, params) { override fun doWork(): Result { + backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) + for (user in userAccountManager.allUsers) { // only if security guard is enabled if (!CapabilityUtils.getCapability(user, context).securityGuard.isTrue) { @@ -92,7 +95,9 @@ class HealthStatusWork( } } - return Result.success() + val result = Result.success() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result } private fun collectSyncConflicts(user: User): Problem? { diff --git a/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt b/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt index eae4c7476b93..d6f644fa3f33 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt @@ -29,9 +29,9 @@ data class JobInfo( val state: String = "", val name: String = "", val user: String = "", + val workerClass: String = "", val started: Date = Date(0), val progress: Int = 0, - val executionLog: MutableList? = null ) @@ -39,5 +39,5 @@ data class LogEntry ( val started: Date? = null, val finished: Date? = null, val result: String? = null, - var worker: String = "None" + var workerClass: String = BackgroundJobManagerImpl.NOT_SET_VALUE ) diff --git a/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt b/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt index 6be8c5d5058d..ca7fdb712855 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt @@ -24,6 +24,7 @@ import android.content.ContextWrapper import androidx.work.Configuration import androidx.work.WorkManager import com.nextcloud.client.core.Clock +import com.nextcloud.client.preferences.AppPreferences import dagger.Module import dagger.Provides import javax.inject.Singleton @@ -50,7 +51,7 @@ class JobsModule { @Provides @Singleton - fun backgroundJobManager(workManager: WorkManager, clock: Clock): BackgroundJobManager { - return BackgroundJobManagerImpl(workManager, clock) + fun backgroundJobManager(workManager: WorkManager, clock: Clock, preferences: AppPreferences): BackgroundJobManager { + return BackgroundJobManagerImpl(workManager, clock, preferences) } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt b/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt index 0cd0684cd44a..e74b6527708a 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt @@ -26,7 +26,8 @@ import androidx.work.WorkerParameters class TestJob( appContext: Context, - params: WorkerParameters + params: WorkerParameters, + private val backgroundJobManager: BackgroundJobManager ) : Worker(appContext, params) { companion object { @@ -36,6 +37,8 @@ class TestJob( } override fun doWork(): Result { + backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) + for (i in 0..MAX_PROGRESS) { Thread.sleep(DELAY_MS) val progress = Data.Builder() @@ -43,6 +46,9 @@ class TestJob( .build() setProgressAsync(progress) } - return Result.success() + + val result = Result.success() + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + return result } } diff --git a/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java b/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java index 592311c3a096..4643f18dbc82 100644 --- a/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java +++ b/app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java @@ -53,6 +53,7 @@ import androidx.annotation.VisibleForTesting; import static com.owncloud.android.ui.fragment.OCFileListFragment.FOLDER_LAYOUT_LIST; +import static java.util.Collections.emptyList; /** * Implementation of application-wide preferences using {@link SharedPreferences}. @@ -515,6 +516,7 @@ public void saveLogEntry(List logEntryList) { @Override public List readLogEntry() { String json = preferences.getString(LOG_ENTRY, null); + if (json == null) return emptyList(); Gson gson = new Gson(); Type listType = new TypeToken>() {}.getType(); return gson.fromJson(json, listType); diff --git a/app/src/main/res/layout/etm_background_job_list_item.xml b/app/src/main/res/layout/etm_background_job_list_item.xml index 5ee0b62a173f..1801d2f7bd22 100644 --- a/app/src/main/res/layout/etm_background_job_list_item.xml +++ b/app/src/main/res/layout/etm_background_job_list_item.xml @@ -137,8 +137,10 @@ + android:layout_height="match_parent" + android:visibility="visible"> - + android:layout_height="wrap_content" > - + android:fadeScrollbars="false" + android:scrollbars="horizontal" + android:scrollHorizontally="true"> - - - + + + + + - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 46d7fa4513d6..388bc6d1faa3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -878,7 +878,7 @@ Job name User State - Started + Created Progress Times run in 48h Execution logs From 885aa703e8263f15559181353aa7c56fb9ce2018 Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Tue, 19 Dec 2023 14:25:45 +0100 Subject: [PATCH 3/6] Fix spotless issues Signed-off-by: Jonas Mayer --- .../etm/pages/EtmBackgroundJobsFragment.kt | 33 +++++++++------ .../client/jobs/BackgroundJobFactory.kt | 18 ++++---- .../client/jobs/BackgroundJobManager.kt | 2 +- .../client/jobs/BackgroundJobManagerImpl.kt | 41 +++++++++---------- .../client/jobs/ContentObserverWork.kt | 2 +- .../nextcloud/client/jobs/FilesSyncWork.kt | 4 +- .../client/jobs/FilesUploadWorker.kt | 4 +- .../nextcloud/client/jobs/HealthStatusWork.kt | 2 +- .../java/com/nextcloud/client/jobs/JobInfo.kt | 7 +--- .../com/nextcloud/client/jobs/JobsModule.kt | 6 ++- .../java/com/nextcloud/client/jobs/TestJob.kt | 2 +- 11 files changed, 63 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt index 2da0f79d4a8e..9f9a6b9ec96a 100644 --- a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt +++ b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt @@ -46,9 +46,10 @@ import javax.inject.Inject class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable { @Inject - lateinit var preferences : AppPreferences + lateinit var preferences: AppPreferences - class Adapter(private val inflater: LayoutInflater, private val preferences: AppPreferences) : RecyclerView.Adapter(){ + class Adapter(private val inflater: LayoutInflater, private val preferences: AppPreferences) : + RecyclerView.Adapter() { class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val uuid = view.findViewById(R.id.etm_background_job_uuid) @@ -88,7 +89,6 @@ class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable { View.GONE } } - } private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:MM:ssZ", Locale.getDefault()) @@ -128,31 +128,33 @@ class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable { vh.progressEnabled = false } - val logs = preferences.readLogEntry() - val logsForThisWorker = logs.filter { BackgroundJobManagerImpl.parseTag(it.workerClass)?.second == info.workerClass } - if(logsForThisWorker.isNotEmpty()) { + val logs = preferences.readLogEntry() + val logsForThisWorker = + logs.filter { BackgroundJobManagerImpl.parseTag(it.workerClass)?.second == info.workerClass } + if (logsForThisWorker.isNotEmpty()) { vh.executionTimesRow.visibility = View.VISIBLE - vh.executionCount.text = logsForThisWorker.filter { it.started != null }.size.toString() + " (${logsForThisWorker.filter { it.finished != null }.size})" + vh.executionCount.text = + "${logsForThisWorker.filter { it.started != null }.size} " + + "(${logsForThisWorker.filter { it.finished != null }.size})" var logText = "Worker Logs\n\n" + - "*** Does NOT differentiate between imitate or periodic kinds of Work! ***\n"+ + "*** Does NOT differentiate between imitate or periodic kinds of Work! ***\n" + "*** Times run in 48h: Times started (Times finished) ***\n" - logsForThisWorker.forEach{ + logsForThisWorker.forEach { logText += "----------------------\n" logText += "Worker ${BackgroundJobManagerImpl.parseTag(it.workerClass)?.second}\n" - logText += if (it.started == null){ + logText += if (it.started == null) { "ENDED at\n${it.finished}\nWith result: ${it.result}\n" - }else{ + } else { "STARTED at\n${it.started}\n" } } vh.executionLog.text = logText - }else{ + } else { vh.executionLog.text = "Worker Logs\n\n" + "No Entries -> Maybe logging is not implemented for Worker or it has not run yet." vh.executionCount.text = "0" vh.executionTimesRow.visibility = View.GONE } - } } @@ -186,22 +188,27 @@ class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable { vm.cancelAllJobs() true } + R.id.etm_background_jobs_prune -> { vm.pruneJobs() true } + R.id.etm_background_jobs_start_test -> { vm.startTestJob(periodic = false) true } + R.id.etm_background_jobs_schedule_test -> { vm.startTestJob(periodic = true) true } + R.id.etm_background_jobs_cancel_test -> { vm.cancelTestJob() true } + else -> super.onOptionsItemSelected(item) } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt index f126f869e1e9..cc8c999dcabb 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobFactory.kt @@ -51,7 +51,7 @@ import javax.inject.Provider * * This class is doing too many things and should be split up into smaller factories. */ -@Suppress("LongParameterList") // satisfied by DI +@Suppress("LongParameterList", "TooManyFunctions") // satisfied by DI class BackgroundJobFactory @Inject constructor( private val logger: Logger, private val preferences: AppPreferences, @@ -143,7 +143,7 @@ class BackgroundJobFactory @Inject constructor( resources, arbitraryDataProvider, contentResolver, - accountManager, + accountManager ) } @@ -152,7 +152,7 @@ class BackgroundJobFactory @Inject constructor( context, params, logger, - contentResolver, + contentResolver ) } @@ -162,7 +162,7 @@ class BackgroundJobFactory @Inject constructor( params, contentResolver, accountManager, - preferences, + preferences ) } @@ -171,7 +171,7 @@ class BackgroundJobFactory @Inject constructor( context, params, logger, - contentResolver, + contentResolver ) } @@ -210,7 +210,7 @@ class BackgroundJobFactory @Inject constructor( preferences, clock, viewThemeUtils.get(), - syncedFolderProvider, + syncedFolderProvider ) } @@ -221,7 +221,7 @@ class BackgroundJobFactory @Inject constructor( notificationManager, accountManager, deckApi, - viewThemeUtils.get(), + viewThemeUtils.get() ) } @@ -249,7 +249,7 @@ class BackgroundJobFactory @Inject constructor( localBroadcastManager.get(), backgroundJobManager.get(), context, - params, + params ) } @@ -261,7 +261,7 @@ class BackgroundJobFactory @Inject constructor( notificationManager = notificationManager, userAccountManager = accountManager, logger = logger, - params = params, + params = params ) } diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt index 4fa8a68b2e44..750e967ccea9 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManager.kt @@ -36,7 +36,7 @@ interface BackgroundJobManager { */ val jobs: LiveData> - fun logStartOfWorker(workerName : String?) + fun logStartOfWorker(workerName: String?) fun logEndOfWorker(workerName: String?, result: ListenableWorker.Result) diff --git a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt index 53a787928f65..68bf01dcda36 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/BackgroundJobManagerImpl.kt @@ -66,7 +66,6 @@ internal class BackgroundJobManagerImpl( private val preferences: AppPreferences ) : BackgroundJobManager, Injectable { - companion object { const val TAG_ALL = "*" // This tag allows us to retrieve list of all jobs run by Nextcloud client @@ -105,7 +104,7 @@ internal class BackgroundJobManagerImpl( const val DEFAULT_PERIODIC_JOB_INTERVAL_MINUTES = 15L const val DEFAULT_IMMEDIATE_JOB_DELAY_SEC = 3L - private const val KEEP_LOG_MILLIS = 1000 * 60 * 60 * 24 *3L + private const val KEEP_LOG_MILLIS = 1000 * 60 * 60 * 24 * 3L fun formatNameTag(name: String, user: User? = null): String { return if (user == null) { @@ -130,11 +129,11 @@ internal class BackgroundJobManagerImpl( } fun parseTimestamp(timestamp: String): Date { - try { + return try { val ms = timestamp.toLong() - return Date(ms) + Date(ms) } catch (ex: NumberFormatException) { - return Date(0) + Date(0) } } @@ -161,40 +160,38 @@ internal class BackgroundJobManagerImpl( } } - fun deleteOldLogs(logEntries: MutableList) : MutableList{ - + fun deleteOldLogs(logEntries: MutableList): MutableList { logEntries.removeIf { - return@removeIf (it.started != null && - Date(Date().time - KEEP_LOG_MILLIS).after(it.started)) || - (it.finished != null && - Date(Date().time - KEEP_LOG_MILLIS).after(it.finished)) - + return@removeIf ( + it.started != null && + Date(Date().time - KEEP_LOG_MILLIS).after(it.started) + ) || + ( + it.finished != null && + Date(Date().time - KEEP_LOG_MILLIS).after(it.finished) + ) } return logEntries - } - - } - override fun logStartOfWorker(workerName : String?) { + override fun logStartOfWorker(workerName: String?) { val logs = deleteOldLogs(preferences.readLogEntry().toMutableList()) if (workerName == null) { logs.add(LogEntry(Date(), null, null, NOT_SET_VALUE)) - }else{ + } else { logs.add(LogEntry(Date(), null, null, workerName)) } preferences.saveLogEntry(logs) } - override fun logEndOfWorker(workerName: String?, result: ListenableWorker.Result){ - + override fun logEndOfWorker(workerName: String?, result: ListenableWorker.Result) { val logs = deleteOldLogs(preferences.readLogEntry().toMutableList()) if (workerName == null) { - logs.add(LogEntry(null,Date(),result.toString(), NOT_SET_VALUE)) - }else{ - logs.add(LogEntry(null,Date(),result.toString(),workerName)) + logs.add(LogEntry(null, Date(), result.toString(), NOT_SET_VALUE)) + } else { + logs.add(LogEntry(null, Date(), result.toString(), workerName)) } preferences.saveLogEntry(logs) } diff --git a/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt b/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt index 99117678a833..4e9840ccef35 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/ContentObserverWork.kt @@ -50,7 +50,7 @@ class ContentObserverWork( recheduleSelf() val result = Result.success() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result } diff --git a/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt b/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt index 1246b0a333ff..9d98b0404bc8 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt @@ -81,7 +81,7 @@ class FilesSyncWork( // If we are in power save mode, better to postpone upload if (powerManagementService.isPowerSavingEnabled && !overridePowerSaving) { val result = Result.success() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result } val resources = context.resources @@ -113,7 +113,7 @@ class FilesSyncWork( } } val result = Result.success() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result } diff --git a/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt index 2563b943667a..ce3516740a6f 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/FilesUploadWorker.kt @@ -88,7 +88,7 @@ class FilesUploadWorker( Log_OC.w(TAG, "User was null for file upload worker") val result = Result.failure() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result // user account is needed } @@ -107,7 +107,7 @@ class FilesUploadWorker( Log_OC.d(TAG, "No more pending uploads for account $accountName, stopping work") val result = Result.success() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result // user account is needed } diff --git a/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt b/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt index 2512f42e706d..bd59f07fe6e0 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/HealthStatusWork.kt @@ -96,7 +96,7 @@ class HealthStatusWork( } val result = Result.success() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result } diff --git a/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt b/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt index d6f644fa3f33..95379fcbf023 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/JobInfo.kt @@ -19,8 +19,6 @@ */ package com.nextcloud.client.jobs -import androidx.work.ListenableWorker -import com.google.common.util.concurrent.ListenableFuture import java.util.Date import java.util.UUID @@ -31,11 +29,10 @@ data class JobInfo( val user: String = "", val workerClass: String = "", val started: Date = Date(0), - val progress: Int = 0, + val progress: Int = 0 ) - -data class LogEntry ( +data class LogEntry( val started: Date? = null, val finished: Date? = null, val result: String? = null, diff --git a/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt b/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt index ca7fdb712855..79f2f2386c3d 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/JobsModule.kt @@ -51,7 +51,11 @@ class JobsModule { @Provides @Singleton - fun backgroundJobManager(workManager: WorkManager, clock: Clock, preferences: AppPreferences): BackgroundJobManager { + fun backgroundJobManager( + workManager: WorkManager, + clock: Clock, + preferences: AppPreferences + ): BackgroundJobManager { return BackgroundJobManagerImpl(workManager, clock, preferences) } } diff --git a/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt b/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt index e74b6527708a..cfd9e996c0a3 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/TestJob.kt @@ -48,7 +48,7 @@ class TestJob( } val result = Result.success() - backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class),result) + backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) return result } } From bbecd6e2bc371a4a6bfa07755f613c67f7ecb9d6 Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Tue, 19 Dec 2023 14:47:39 +0100 Subject: [PATCH 4/6] Fix unused resource Signed-off-by: Jonas Mayer --- app/src/main/res/values/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 388bc6d1faa3..16526b0bc265 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -881,7 +881,6 @@ Created Progress Times run in 48h - Execution logs Migrations (app upgrade) File transfer Remote path From 979a13cbb62f17874c0b092475da0262db5ca6a0 Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Wed, 20 Dec 2023 10:00:29 +0100 Subject: [PATCH 5/6] Fix failing tests, fix typo Signed-off-by: Jonas Mayer --- .../com/nextcloud/client/jobs/BackgroundJobManagerTest.kt | 2 +- .../java/com/nextcloud/client/jobs/ContactsBackupIT.kt | 5 ++++- .../nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt b/app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt index e06adbecbce9..28560deb9615 100644 --- a/app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt +++ b/app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt @@ -104,7 +104,7 @@ class BackgroundJobManagerTest { clock = mock() whenever(clock.currentTime).thenReturn(TIMESTAMP) whenever(clock.currentDate).thenReturn(Date(TIMESTAMP)) - backgroundJobManager = BackgroundJobManagerImpl(workManager, clock) + backgroundJobManager = BackgroundJobManagerImpl(workManager, clock, mock()) } fun assertHasRequiredTags(tags: Set, jobName: String, user: User? = null) { diff --git a/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt b/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt index c4235d553f5c..c915af0f27fa 100644 --- a/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt +++ b/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt @@ -25,6 +25,7 @@ import android.Manifest import androidx.test.rule.GrantPermissionRule import androidx.work.WorkManager import com.nextcloud.client.core.ClockImpl +import com.nextcloud.client.preferences.AppPreferencesImpl import com.nextcloud.test.RetryTestRule import com.owncloud.android.AbstractIT import com.owncloud.android.AbstractOnServerIT @@ -43,7 +44,9 @@ import java.io.FileInputStream class ContactsBackupIT : AbstractOnServerIT() { val workmanager = WorkManager.getInstance(targetContext) - private val backgroundJobManager = BackgroundJobManagerImpl(workmanager, ClockImpl()) + val preferences = AppPreferencesImpl.fromContext(targetContext) + private val backgroundJobManager = BackgroundJobManagerImpl(workmanager, ClockImpl(), preferences) + @get:Rule val writeContactsRule = GrantPermissionRule.grant(Manifest.permission.WRITE_CONTACTS) diff --git a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt index 9f9a6b9ec96a..d55caec0b0ae 100644 --- a/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt +++ b/app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt @@ -137,7 +137,7 @@ class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable { "${logsForThisWorker.filter { it.started != null }.size} " + "(${logsForThisWorker.filter { it.finished != null }.size})" var logText = "Worker Logs\n\n" + - "*** Does NOT differentiate between imitate or periodic kinds of Work! ***\n" + + "*** Does NOT differentiate between immediate or periodic kinds of Work! ***\n" + "*** Times run in 48h: Times started (Times finished) ***\n" logsForThisWorker.forEach { logText += "----------------------\n" From e51cdf665863f4eac9a73e81226686c0f67b4495 Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Wed, 20 Dec 2023 10:08:37 +0100 Subject: [PATCH 6/6] fix spotless error Signed-off-by: Jonas Mayer --- .../java/com/nextcloud/client/jobs/ContactsBackupIT.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt b/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt index c915af0f27fa..5ff30f3af6bb 100644 --- a/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt +++ b/app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt @@ -47,7 +47,6 @@ class ContactsBackupIT : AbstractOnServerIT() { val preferences = AppPreferencesImpl.fromContext(targetContext) private val backgroundJobManager = BackgroundJobManagerImpl(workmanager, ClockImpl(), preferences) - @get:Rule val writeContactsRule = GrantPermissionRule.grant(Manifest.permission.WRITE_CONTACTS)