Skip to content

Commit ec8698c

Browse files
committed
AND-18021: Add Worker pending list logs
1 parent 4730989 commit ec8698c

File tree

10 files changed

+94
-37
lines changed

10 files changed

+94
-37
lines changed

app/src/gms/java/mega/privacy/android/app/service/push/MegaMessageService.kt

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,33 @@
11
package mega.privacy.android.app.service.push
22

3-
import android.content.Context
43
import androidx.work.Data
54
import androidx.work.WorkManager
6-
import com.google.android.gms.tasks.Task
75
import com.google.firebase.messaging.FirebaseMessaging
86
import com.google.firebase.messaging.FirebaseMessagingService
97
import com.google.firebase.messaging.RemoteMessage
108
import dagger.hilt.android.AndroidEntryPoint
9+
import kotlinx.coroutines.CoroutineScope
10+
import kotlinx.coroutines.launch
11+
import kotlinx.coroutines.sync.Mutex
12+
import kotlinx.coroutines.sync.withLock
13+
import kotlinx.coroutines.tasks.await
1114
import mega.privacy.android.app.data.extensions.enqueuePushMessage
1215
import mega.privacy.android.app.data.extensions.enqueueUniqueWorkNewToken
1316
import mega.privacy.android.app.utils.Constants.DEVICE_ANDROID
17+
import mega.privacy.android.domain.qualifier.ApplicationScope
1418
import timber.log.Timber
15-
import java.util.concurrent.Executors
19+
import javax.inject.Inject
1620

1721
@AndroidEntryPoint
1822
class MegaMessageService : FirebaseMessagingService() {
1923

24+
@Inject
25+
@ApplicationScope
26+
lateinit var applicationScope: CoroutineScope
27+
28+
@Inject
29+
lateinit var workManager: WorkManager
30+
2031
override fun onDestroy() {
2132
Timber.d("onDestroy")
2233
super.onDestroy()
@@ -27,15 +38,17 @@ class MegaMessageService : FirebaseMessagingService() {
2738

2839
val workerData = remoteMessage.data.toWorkerData()
2940

30-
WorkManager.getInstance(this)
31-
.enqueuePushMessage(workerData)
41+
applicationScope.launch {
42+
workManager.enqueuePushMessage(workerData)
43+
}
3244
}
3345

3446
override fun onNewToken(token: String) {
3547
Timber.d("New token: $token")
3648

37-
WorkManager.getInstance(this)
38-
.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID)
49+
applicationScope.launch {
50+
workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID)
51+
}
3952
}
4053

4154
/**
@@ -49,28 +62,24 @@ class MegaMessageService : FirebaseMessagingService() {
4962
.build()
5063

5164
companion object {
65+
/**
66+
* Mutex to avoid multiple calls to getToken.
67+
*/
68+
private val mutex = Mutex()
69+
5270
/**
5371
* Request push service token, then register it in API as an identifier of the device.
54-
*
55-
* @param context Context.
5672
*/
5773
@JvmStatic
58-
fun getToken(context: Context) {
74+
suspend fun getToken(workManager: WorkManager) {
5975
//project number from google-service.json
60-
Executors.newFixedThreadPool(1).submit {
61-
FirebaseMessaging.getInstance().token.addOnCompleteListener { task: Task<String> ->
62-
if (!task.isSuccessful) {
63-
Timber.w("Get token failed.")
64-
return@addOnCompleteListener
65-
}
66-
67-
// Get new Instance ID token
68-
val token = task.result
69-
Timber.d("Get token: $token")
76+
mutex.withLock {
77+
val token = FirebaseMessaging.getInstance().token.await()
7078

71-
WorkManager.getInstance(context)
72-
.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID)
73-
}
79+
token?.let {
80+
Timber.d("Get token succeeded")
81+
workManager.enqueueUniqueWorkNewToken(token, DEVICE_ANDROID)
82+
} ?: Timber.w("Get token failed.")
7483
}
7584
}
7685
}

app/src/main/java/mega/privacy/android/app/data/extensions/WorkManager.kt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import androidx.work.OutOfQuotaPolicy
77
import androidx.work.WorkManager
88
import mega.privacy.android.app.fcm.NewTokenWorker
99
import mega.privacy.android.app.fcm.PushMessageWorker
10+
import mega.privacy.android.data.facade.debugWorkInfo
1011

1112
/**
1213
* Enqueues a [PushMessageWorker] request to manage a push notification.
1314
*
1415
* @param data [Data] containing the push information.
1516
*/
16-
fun WorkManager.enqueuePushMessage(data: Data) {
17+
suspend fun WorkManager.enqueuePushMessage(data: Data) {
18+
debugWorkInfo()
19+
1720
enqueue(
1821
OneTimeWorkRequestBuilder<PushMessageWorker>()
1922
.setInputData(data)
@@ -28,7 +31,9 @@ fun WorkManager.enqueuePushMessage(data: Data) {
2831
* @param newToken Required token for register pushes.
2932
* @param deviceType Type of device.
3033
*/
31-
fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) {
34+
suspend fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) {
35+
debugWorkInfo()
36+
3237
enqueueUniqueWork(
3338
NewTokenWorker.WORK_NAME,
3439
ExistingWorkPolicy.REPLACE,
@@ -42,4 +47,4 @@ fun WorkManager.enqueueUniqueWorkNewToken(newToken: String, deviceType: Int) {
4247
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
4348
.build()
4449
)
45-
}
50+
}

app/src/main/java/mega/privacy/android/app/main/ManagerActivity.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import androidx.navigation.NavDestination
6666
import androidx.navigation.NavOptions
6767
import androidx.navigation.fragment.NavHostFragment
6868
import androidx.viewpager2.widget.ViewPager2
69+
import androidx.work.WorkManager
6970
import com.google.android.material.appbar.AppBarLayout
7071
import com.google.android.material.appbar.MaterialToolbar
7172
import com.google.android.material.bottomnavigation.BottomNavigationItemView
@@ -83,6 +84,7 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
8384
import io.reactivex.rxjava3.kotlin.addTo
8485
import io.reactivex.rxjava3.schedulers.Schedulers
8586
import kotlinx.coroutines.CoroutineDispatcher
87+
import kotlinx.coroutines.CoroutineScope
8688
import kotlinx.coroutines.Job
8789
import kotlinx.coroutines.flow.firstOrNull
8890
import kotlinx.coroutines.launch
@@ -300,6 +302,7 @@ import mega.privacy.android.domain.exception.QuotaExceededMegaException
300302
import mega.privacy.android.domain.exception.chat.IAmOnAnotherCallException
301303
import mega.privacy.android.domain.exception.chat.MeetingEndedException
302304
import mega.privacy.android.domain.exception.node.ForeignNodeException
305+
import mega.privacy.android.domain.qualifier.ApplicationScope
303306
import mega.privacy.android.domain.qualifier.IoDispatcher
304307
import mega.privacy.android.domain.usecase.GetChatRoomUseCase
305308
import mega.privacy.android.domain.usecase.chat.HasArchivedChatsUseCase
@@ -452,6 +455,13 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf
452455
@Inject
453456
lateinit var syncNavigator: SyncNavigator
454457

458+
@Inject
459+
lateinit var workManager: WorkManager
460+
461+
@Inject
462+
@ApplicationScope
463+
lateinit var applicationScope: CoroutineScope
464+
455465
//GET PRO ACCOUNT PANEL
456466
private lateinit var getProLayout: LinearLayout
457467
private lateinit var getProText: TextView
@@ -1385,7 +1395,9 @@ class ManagerActivity : TransfersManagementActivity(), MegaRequestListenerInterf
13851395
megaApi.invalidateCache()
13861396
}
13871397
dbH.setInvalidateSdkCache(false)
1388-
MegaMessageService.getToken(this)
1398+
applicationScope.launch {
1399+
MegaMessageService.getToken(workManager)
1400+
}
13891401
userInfoViewModel.getUserInfo()
13901402
preloadPayment()
13911403
megaApi.isGeolocationEnabled(this)

data/src/main/java/mega/privacy/android/data/facade/WorkManagerFacade.kt

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import androidx.work.OneTimeWorkRequest
77
import androidx.work.PeriodicWorkRequest
88
import androidx.work.WorkInfo
99
import androidx.work.WorkManager
10+
import androidx.work.WorkQuery
1011
import androidx.work.await
1112
import kotlinx.coroutines.flow.Flow
13+
import kotlinx.coroutines.flow.firstOrNull
1214
import kotlinx.coroutines.flow.mapNotNull
1315
import kotlinx.coroutines.flow.merge
1416
import mega.privacy.android.data.gateway.WorkManagerGateway
@@ -41,6 +43,8 @@ internal class WorkManagerFacade @Inject constructor(
4143
) : WorkManagerGateway {
4244

4345
override suspend fun enqueueDeleteOldestCompletedTransfersWorkRequest() {
46+
workManager.debugWorkInfo()
47+
4448
val workRequest =
4549
OneTimeWorkRequest.Builder(DeleteOldestCompletedTransfersWorker::class.java)
4650
.addTag(DeleteOldestCompletedTransfersWorker.DELETE_OLDEST_TRANSFERS_WORKER_TAG)
@@ -54,7 +58,9 @@ internal class WorkManagerFacade @Inject constructor(
5458
)
5559
}
5660

57-
override fun enqueueDownloadsWorkerRequest() {
61+
override suspend fun enqueueDownloadsWorkerRequest() {
62+
workManager.debugWorkInfo()
63+
5864
val request = OneTimeWorkRequest.Builder(DownloadsWorker::class.java)
5965
.addTag(DownloadsWorker.SINGLE_DOWNLOAD_TAG)
6066
.build()
@@ -69,6 +75,8 @@ internal class WorkManagerFacade @Inject constructor(
6975
override suspend fun startCameraUploads() {
7076
// Check if CU periodic worker is working. If yes, then don't start a single one
7177
if (!checkWorkerRunning(CAMERA_UPLOAD_TAG)) {
78+
workManager.debugWorkInfo()
79+
7280
Timber.d("No CU periodic process currently running, proceed with one time request")
7381
val cameraUploadWorkRequest = OneTimeWorkRequest.Builder(
7482
CameraUploadsWorker::class.java
@@ -111,6 +119,9 @@ internal class WorkManagerFacade @Inject constructor(
111119

112120
override suspend fun scheduleCameraUploads() {
113121
scheduleCameraUploadSyncActiveHeartbeat()
122+
123+
workManager.debugWorkInfo()
124+
114125
// periodic work that runs during the last 10 minutes of every one hour period
115126
val cameraUploadWorkRequest = PeriodicWorkRequest.Builder(
116127
CameraUploadsWorker::class.java,
@@ -139,6 +150,8 @@ internal class WorkManagerFacade @Inject constructor(
139150
* Schedule camera uploads active heartbeat worker
140151
*/
141152
private suspend fun scheduleCameraUploadSyncActiveHeartbeat() {
153+
workManager.debugWorkInfo()
154+
142155
// periodic work that runs during the last 10 minutes of every half an hour period
143156
val cuSyncActiveHeartbeatWorkRequest = PeriodicWorkRequest.Builder(
144157
SyncHeartbeatCameraUploadWorker::class.java,
@@ -223,3 +236,17 @@ internal class WorkManagerFacade @Inject constructor(
223236
override fun monitorDownloadsStatusInfo() =
224237
workManager.getWorkInfosByTagFlow(DownloadsWorker.SINGLE_DOWNLOAD_TAG)
225238
}
239+
240+
/**
241+
* Prints the list of pending [WorkInfo] in the log.
242+
*/
243+
suspend fun WorkManager.debugWorkInfo() {
244+
getWorkInfosFlow(
245+
WorkQuery.fromStates(
246+
WorkInfo.State.ENQUEUED,
247+
)
248+
).firstOrNull()
249+
?.map { it.tags }
250+
?.let { Timber.d("Worker pending list: $it") }
251+
?: Timber.d("Worker pending list: empty")
252+
}

data/src/main/java/mega/privacy/android/data/gateway/WorkManagerGateway.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ interface WorkManagerGateway {
1616
/**
1717
* Enqueue unique work request to start download worker to monitor the download transfers as a foreground service
1818
*/
19-
fun enqueueDownloadsWorkerRequest()
19+
suspend fun enqueueDownloadsWorkerRequest()
2020

2121
/**
2222
* Queue a one time work request of camera upload to upload immediately.

data/src/main/java/mega/privacy/android/data/repository/DefaultTransfersRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ internal class DefaultTransfersRepository @Inject constructor(
457457
workerManagerGateway.enqueueDeleteOldestCompletedTransfersWorkRequest()
458458
}
459459

460-
override fun startDownloadWorker() {
460+
override suspend fun startDownloadWorker() = withContext(ioDispatcher) {
461461
workerManagerGateway.enqueueDownloadsWorkerRequest()
462462
}
463463

data/src/main/java/mega/privacy/android/data/worker/NewMediaWorker.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.work.WorkManager
1212
import androidx.work.WorkerParameters
1313
import dagger.assisted.Assisted
1414
import dagger.assisted.AssistedInject
15+
import mega.privacy.android.data.facade.debugWorkInfo
1516
import mega.privacy.android.domain.usecase.camerauploads.IsCameraUploadsEnabledUseCase
1617
import mega.privacy.android.domain.usecase.workers.StartCameraUploadUseCase
1718
import timber.log.Timber
@@ -46,6 +47,8 @@ internal class NewMediaWorker @AssistedInject constructor(
4647
if (isForce
4748
|| isQueuedOrRunning(workManager)
4849
) {
50+
workManager.debugWorkInfo()
51+
4952
val photoCheckBuilder =
5053
OneTimeWorkRequest.Builder(NewMediaWorker::class.java)
5154
photoCheckBuilder.setConstraints(

data/src/test/java/mega/privacy/android/data/repository/DefaultTransfersRepositoryTest.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,10 +1087,11 @@ class DefaultTransfersRepositoryTest {
10871087
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
10881088
inner class WorkerTests {
10891089
@Test
1090-
fun `test that workerManagerGateway enqueueDownloadsWorkerRequest is called when startDownloadWorker is called`() {
1091-
underTest.startDownloadWorker()
1092-
verify(workerManagerGateway).enqueueDownloadsWorkerRequest()
1093-
}
1090+
fun `test that workerManagerGateway enqueueDownloadsWorkerRequest is called when startDownloadWorker is called`() =
1091+
runTest {
1092+
underTest.startDownloadWorker()
1093+
verify(workerManagerGateway).enqueueDownloadsWorkerRequest()
1094+
}
10941095

10951096
@ParameterizedTest
10961097
@EnumSource(WorkInfo.State::class)

domain/src/main/kotlin/mega/privacy/android/domain/repository/TransferRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ interface TransferRepository {
253253
/**
254254
* Starts the download worker to monitor the download transfers as a foreground service
255255
*/
256-
fun startDownloadWorker()
256+
suspend fun startDownloadWorker()
257257

258258
/**
259259
* Monitors transfers finished.

domain/src/main/kotlin/mega/privacy/android/domain/usecase/transfers/downloads/StartDownloadWorkerUseCase.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ class StartDownloadWorkerUseCase @Inject constructor(
1616
* Invoke.
1717
*
1818
*/
19-
operator fun invoke() = transferRepository.startDownloadWorker()
20-
}
19+
suspend operator fun invoke() = transferRepository.startDownloadWorker()
20+
}

0 commit comments

Comments
 (0)