Skip to content

Commit 14a6d65

Browse files
Merge pull request nextcloud#12306 from nextcloud/add-info-for-background-worker
Add info for background worker execution
2 parents 251ef24 + e51cdf6 commit 14a6d65

18 files changed

Lines changed: 298 additions & 29 deletions

app/src/androidTest/java/com/nextcloud/client/jobs/BackgroundJobManagerTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class BackgroundJobManagerTest {
104104
clock = mock()
105105
whenever(clock.currentTime).thenReturn(TIMESTAMP)
106106
whenever(clock.currentDate).thenReturn(Date(TIMESTAMP))
107-
backgroundJobManager = BackgroundJobManagerImpl(workManager, clock)
107+
backgroundJobManager = BackgroundJobManagerImpl(workManager, clock, mock())
108108
}
109109

110110
fun assertHasRequiredTags(tags: Set<String>, jobName: String, user: User? = null) {

app/src/androidTest/java/com/nextcloud/client/jobs/ContactsBackupIT.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import android.Manifest
2525
import androidx.test.rule.GrantPermissionRule
2626
import androidx.work.WorkManager
2727
import com.nextcloud.client.core.ClockImpl
28+
import com.nextcloud.client.preferences.AppPreferencesImpl
2829
import com.nextcloud.test.RetryTestRule
2930
import com.owncloud.android.AbstractIT
3031
import com.owncloud.android.AbstractOnServerIT
@@ -43,7 +44,8 @@ import java.io.FileInputStream
4344

4445
class ContactsBackupIT : AbstractOnServerIT() {
4546
val workmanager = WorkManager.getInstance(targetContext)
46-
private val backgroundJobManager = BackgroundJobManagerImpl(workmanager, ClockImpl())
47+
val preferences = AppPreferencesImpl.fromContext(targetContext)
48+
private val backgroundJobManager = BackgroundJobManagerImpl(workmanager, ClockImpl(), preferences)
4749

4850
@get:Rule
4951
val writeContactsRule = GrantPermissionRule.grant(Manifest.permission.WRITE_CONTACTS)

app/src/main/java/com/nextcloud/client/di/ComponentsModule.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
import com.nextcloud.client.documentscan.DocumentScanActivity;
2424
import com.nextcloud.client.editimage.EditImageActivity;
2525
import com.nextcloud.client.etm.EtmActivity;
26+
import com.nextcloud.client.etm.pages.EtmBackgroundJobsFragment;
2627
import com.nextcloud.client.files.downloader.FileTransferService;
28+
import com.nextcloud.client.jobs.BackgroundJobManagerImpl;
2729
import com.nextcloud.client.jobs.NotificationWork;
30+
import com.nextcloud.client.jobs.TestJob;
2831
import com.nextcloud.client.logger.ui.LogsActivity;
2932
import com.nextcloud.client.logger.ui.LogsViewModel;
3033
import com.nextcloud.client.media.PlayerService;
@@ -478,4 +481,13 @@ abstract class ComponentsModule {
478481

479482
@ContributesAndroidInjector
480483
abstract ImageDetailFragment imageDetailFragment();
484+
485+
@ContributesAndroidInjector
486+
abstract EtmBackgroundJobsFragment etmBackgroundJobsFragment();
487+
488+
@ContributesAndroidInjector
489+
abstract BackgroundJobManagerImpl backgroundJobManagerImpl();
490+
491+
@ContributesAndroidInjector
492+
abstract TestJob testJob();
481493
}

app/src/main/java/com/nextcloud/client/etm/pages/EtmBackgroundJobsFragment.kt

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
package com.nextcloud.client.etm.pages
2222

23+
import android.annotation.SuppressLint
2324
import android.os.Bundle
2425
import android.view.LayoutInflater
2526
import android.view.Menu
@@ -32,15 +33,23 @@ import androidx.lifecycle.Observer
3233
import androidx.recyclerview.widget.DividerItemDecoration
3334
import androidx.recyclerview.widget.LinearLayoutManager
3435
import androidx.recyclerview.widget.RecyclerView
36+
import com.nextcloud.client.di.Injectable
3537
import com.nextcloud.client.etm.EtmBaseFragment
38+
import com.nextcloud.client.jobs.BackgroundJobManagerImpl
3639
import com.nextcloud.client.jobs.JobInfo
40+
import com.nextcloud.client.preferences.AppPreferences
3741
import com.owncloud.android.R
3842
import java.text.SimpleDateFormat
3943
import java.util.Locale
44+
import javax.inject.Inject
4045

41-
class EtmBackgroundJobsFragment : EtmBaseFragment() {
46+
class EtmBackgroundJobsFragment : EtmBaseFragment(), Injectable {
4247

43-
class Adapter(private val inflater: LayoutInflater) : RecyclerView.Adapter<Adapter.ViewHolder>() {
48+
@Inject
49+
lateinit var preferences: AppPreferences
50+
51+
class Adapter(private val inflater: LayoutInflater, private val preferences: AppPreferences) :
52+
RecyclerView.Adapter<Adapter.ViewHolder>() {
4453

4554
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
4655
val uuid = view.findViewById<TextView>(R.id.etm_background_job_uuid)
@@ -50,6 +59,10 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() {
5059
val started = view.findViewById<TextView>(R.id.etm_background_job_started)
5160
val progress = view.findViewById<TextView>(R.id.etm_background_job_progress)
5261
private val progressRow = view.findViewById<View>(R.id.etm_background_job_progress_row)
62+
val executionCount = view.findViewById<TextView>(R.id.etm_background_execution_count)
63+
val executionLog = view.findViewById<TextView>(R.id.etm_background_execution_logs)
64+
private val executionLogRow = view.findViewById<View>(R.id.etm_background_execution_logs_row)
65+
val executionTimesRow = view.findViewById<View>(R.id.etm_background_execution_times_row)
5366

5467
var progressEnabled: Boolean = progressRow.visibility == View.VISIBLE
5568
get() {
@@ -63,6 +76,19 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() {
6376
View.GONE
6477
}
6578
}
79+
80+
var logsEnabled: Boolean = executionLogRow.visibility == View.VISIBLE
81+
get() {
82+
return executionLogRow.visibility == View.VISIBLE
83+
}
84+
set(value) {
85+
field = value
86+
executionLogRow.visibility = if (value) {
87+
View.VISIBLE
88+
} else {
89+
View.GONE
90+
}
91+
}
6692
}
6793

6894
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:MM:ssZ", Locale.getDefault())
@@ -74,13 +100,20 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() {
74100

75101
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
76102
val view = inflater.inflate(R.layout.etm_background_job_list_item, parent, false)
77-
return ViewHolder(view)
103+
val viewHolder = ViewHolder(view)
104+
viewHolder.logsEnabled = false
105+
viewHolder.executionTimesRow.visibility = View.GONE
106+
view.setOnClickListener {
107+
viewHolder.logsEnabled = !viewHolder.logsEnabled
108+
}
109+
return viewHolder
78110
}
79111

80112
override fun getItemCount(): Int {
81113
return backgroundJobs.size
82114
}
83115

116+
@SuppressLint("SetTextI18n")
84117
override fun onBindViewHolder(vh: ViewHolder, position: Int) {
85118
val info = backgroundJobs[position]
86119
vh.uuid.text = info.id.toString()
@@ -94,6 +127,34 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() {
94127
} else {
95128
vh.progressEnabled = false
96129
}
130+
131+
val logs = preferences.readLogEntry()
132+
val logsForThisWorker =
133+
logs.filter { BackgroundJobManagerImpl.parseTag(it.workerClass)?.second == info.workerClass }
134+
if (logsForThisWorker.isNotEmpty()) {
135+
vh.executionTimesRow.visibility = View.VISIBLE
136+
vh.executionCount.text =
137+
"${logsForThisWorker.filter { it.started != null }.size} " +
138+
"(${logsForThisWorker.filter { it.finished != null }.size})"
139+
var logText = "Worker Logs\n\n" +
140+
"*** Does NOT differentiate between immediate or periodic kinds of Work! ***\n" +
141+
"*** Times run in 48h: Times started (Times finished) ***\n"
142+
logsForThisWorker.forEach {
143+
logText += "----------------------\n"
144+
logText += "Worker ${BackgroundJobManagerImpl.parseTag(it.workerClass)?.second}\n"
145+
logText += if (it.started == null) {
146+
"ENDED at\n${it.finished}\nWith result: ${it.result}\n"
147+
} else {
148+
"STARTED at\n${it.started}\n"
149+
}
150+
}
151+
vh.executionLog.text = logText
152+
} else {
153+
vh.executionLog.text = "Worker Logs\n\n" +
154+
"No Entries -> Maybe logging is not implemented for Worker or it has not run yet."
155+
vh.executionCount.text = "0"
156+
vh.executionTimesRow.visibility = View.GONE
157+
}
97158
}
98159
}
99160

@@ -107,7 +168,7 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() {
107168

108169
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
109170
val view = inflater.inflate(R.layout.fragment_etm_background_jobs, container, false)
110-
adapter = Adapter(inflater)
171+
adapter = Adapter(inflater, preferences)
111172
list = view.findViewById(R.id.etm_background_jobs_list)
112173
list.layoutManager = LinearLayoutManager(context)
113174
list.addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
@@ -127,22 +188,27 @@ class EtmBackgroundJobsFragment : EtmBaseFragment() {
127188
vm.cancelAllJobs()
128189
true
129190
}
191+
130192
R.id.etm_background_jobs_prune -> {
131193
vm.pruneJobs()
132194
true
133195
}
196+
134197
R.id.etm_background_jobs_start_test -> {
135198
vm.startTestJob(periodic = false)
136199
true
137200
}
201+
138202
R.id.etm_background_jobs_schedule_test -> {
139203
vm.startTestJob(periodic = true)
140204
true
141205
}
206+
142207
R.id.etm_background_jobs_cancel_test -> {
143208
vm.cancelTestJob()
144209
true
145210
}
211+
146212
else -> super.onOptionsItemSelected(item)
147213
}
148214
}

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import javax.inject.Provider
5151
*
5252
* This class is doing too many things and should be split up into smaller factories.
5353
*/
54-
@Suppress("LongParameterList") // satisfied by DI
54+
@Suppress("LongParameterList", "TooManyFunctions") // satisfied by DI
5555
class BackgroundJobFactory @Inject constructor(
5656
private val logger: Logger,
5757
private val preferences: AppPreferences,
@@ -104,6 +104,7 @@ class BackgroundJobFactory @Inject constructor(
104104
FilesUploadWorker::class -> createFilesUploadWorker(context, workerParameters)
105105
GeneratePdfFromImagesWork::class -> createPDFGenerateWork(context, workerParameters)
106106
HealthStatusWork::class -> createHealthStatusWork(context, workerParameters)
107+
TestJob::class -> createTestJob(context, workerParameters)
107108
else -> null // caller falls back to default factory
108109
}
109110
}
@@ -183,7 +184,8 @@ class BackgroundJobFactory @Inject constructor(
183184
uploadsStorageManager = uploadsStorageManager,
184185
connectivityService = connectivityService,
185186
powerManagementService = powerManagementService,
186-
syncedFolderProvider = syncedFolderProvider
187+
syncedFolderProvider = syncedFolderProvider,
188+
backgroundJobManager = backgroundJobManager.get()
187189
)
188190
}
189191

@@ -245,6 +247,7 @@ class BackgroundJobFactory @Inject constructor(
245247
accountManager,
246248
viewThemeUtils.get(),
247249
localBroadcastManager.get(),
250+
backgroundJobManager.get(),
248251
context,
249252
params
250253
)
@@ -267,7 +270,16 @@ class BackgroundJobFactory @Inject constructor(
267270
context,
268271
params,
269272
accountManager,
270-
arbitraryDataProvider
273+
arbitraryDataProvider,
274+
backgroundJobManager.get()
275+
)
276+
}
277+
278+
private fun createTestJob(context: Context, params: WorkerParameters): TestJob {
279+
return TestJob(
280+
context,
281+
params,
282+
backgroundJobManager.get()
271283
)
272284
}
273285
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package com.nextcloud.client.jobs
2121

2222
import androidx.lifecycle.LiveData
23+
import androidx.work.ListenableWorker
2324
import com.nextcloud.client.account.User
2425
import com.owncloud.android.datamodel.OCFile
2526

@@ -35,6 +36,10 @@ interface BackgroundJobManager {
3536
*/
3637
val jobs: LiveData<List<JobInfo>>
3738

39+
fun logStartOfWorker(workerName: String?)
40+
41+
fun logEndOfWorker(workerName: String?, result: ListenableWorker.Result)
42+
3843
/**
3944
* Start content observer job that monitors changes in media folders
4045
* and launches synchronization when needed.

0 commit comments

Comments
 (0)