Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Verified Commit 904dd715 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury
Browse files

refactor: remove setRequiresBatteryNotLow(true) constraints from one-time...

refactor: remove setRequiresBatteryNotLow(true) constraints from one-time expedited work for updates

For expedited work requests, only network and storage constraints can be set; other constraints will throw an IllegalArgumentException.

https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:work/work-runtime/src/main/java/androidx/work/WorkRequest.kt;l=303?q=WorkRequest.

Added unit tests for UpdatesWorkManager.
parent a0e8d734
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -46,7 +46,11 @@ object UpdatesWorkManager {

    private fun buildOneTimeWorkRequest(): OneTimeWorkRequest {
        return OneTimeWorkRequest.Builder(UpdatesWorker::class.java).apply {
            setConstraints(buildWorkerConstraints())
            setConstraints(
                Constraints.Builder().apply {
                    setRequiredNetworkType(NetworkType.CONNECTED)
                }.build()
            )
            setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
            addTag(USER_TAG)
        }.setInputData(
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2026 e Foundation
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

package foundation.e.apps.data.install.updates

import android.app.Application
import android.os.Build
import androidx.test.core.app.ApplicationProvider
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.OutOfQuotaPolicy
import androidx.work.WorkInfo
import androidx.work.WorkManager
import androidx.work.impl.WorkManagerImpl
import androidx.work.impl.model.WorkSpec
import androidx.work.testing.WorkManagerTestInitHelper
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import java.util.UUID
import java.util.concurrent.TimeUnit

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [Build.VERSION_CODES.N])
class UpdatesWorkManagerTest {

    private lateinit var context: Application
    private lateinit var workManager: WorkManager

    @Before
    fun setup() {
        context = ApplicationProvider.getApplicationContext()
        WorkManagerTestInitHelper.initializeTestWorkManager(context)
        workManager = WorkManager.getInstance(context)
        workManager.cancelAllWork().result.get()
    }

    @After
    fun teardown() {
        workManager.cancelAllWork().result.get()
    }

    @Test
    fun startUpdateAllWork_buildsExpectedOneTimeRequest() {
        UpdatesWorkManager.startUpdateAllWork(context)

        val workInfo = getActiveUniqueWorkInfo("updates_work_user")
        val workSpec = getWorkSpec(workInfo.id)

        assertThat(workInfo.tags).contains(UpdatesWorkManager.USER_TAG)
        assertThat(workSpec.input.getBoolean(UpdatesWorker.IS_AUTO_UPDATE, true)).isFalse()
        assertThat(workSpec.constraints.requiredNetworkType).isEqualTo(NetworkType.CONNECTED)
        assertThat(workSpec.expedited).isTrue()
        assertThat(workSpec.outOfQuotaPolicy)
            .isEqualTo(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
    }

    @Test
    fun startUpdateAllWork_replacesExistingUniqueWork() {
        UpdatesWorkManager.startUpdateAllWork(context)
        val firstWorkId = getActiveUniqueWorkInfo("updates_work_user").id

        UpdatesWorkManager.startUpdateAllWork(context)

        val allWorkInfos = workManager.getWorkInfosForUniqueWork("updates_work_user").get()
        val activeWorkInfos = allWorkInfos.filter { !it.state.isFinished }

        assertThat(activeWorkInfos).hasSize(1)
        assertThat(activeWorkInfos.single().id).isNotEqualTo(firstWorkId)
    }

    @Test
    fun enqueueWork_buildsExpectedPeriodicRequest() {
        UpdatesWorkManager.enqueueWork(context, interval = 6, ExistingPeriodicWorkPolicy.REPLACE)

        val workInfo = getActiveUniqueWorkInfo("updates_work")
        val workSpec = getWorkSpec(workInfo.id)

        assertThat(workInfo.tags).contains(UpdatesWorkManager.TAG)
        assertThat(workSpec.intervalDuration).isEqualTo(TimeUnit.HOURS.toMillis(6))
        assertThat(workSpec.constraints.requiresBatteryNotLow()).isTrue()
        assertThat(workSpec.constraints.requiredNetworkType).isEqualTo(NetworkType.CONNECTED)
    }

    @Test
    fun enqueueWork_respectsExistingPeriodicWorkPolicy() {
        UpdatesWorkManager.enqueueWork(context, interval = 6, ExistingPeriodicWorkPolicy.KEEP)
        val initialWorkInfo = getActiveUniqueWorkInfo("updates_work")
        val initialWorkSpec = getWorkSpec(initialWorkInfo.id)

        UpdatesWorkManager.enqueueWork(context, interval = 12, ExistingPeriodicWorkPolicy.KEEP)

        val keptWorkInfo = getActiveUniqueWorkInfo("updates_work")
        val keptWorkSpec = getWorkSpec(keptWorkInfo.id)
        assertThat(keptWorkInfo.id).isEqualTo(initialWorkInfo.id)
        assertThat(keptWorkSpec.intervalDuration).isEqualTo(initialWorkSpec.intervalDuration)

        UpdatesWorkManager.enqueueWork(context, interval = 24, ExistingPeriodicWorkPolicy.REPLACE)

        val replacedWorkInfo = getActiveUniqueWorkInfo("updates_work")
        val replacedWorkSpec = getWorkSpec(replacedWorkInfo.id)
        assertThat(replacedWorkInfo.id).isNotEqualTo(initialWorkInfo.id)
        assertThat(replacedWorkSpec.intervalDuration).isEqualTo(TimeUnit.HOURS.toMillis(24))
    }

    private fun getActiveUniqueWorkInfo(uniqueWorkName: String): WorkInfo {
        return workManager.getWorkInfosForUniqueWork(uniqueWorkName).get()
            .single { !it.state.isFinished }
    }

    private fun getWorkSpec(workId: UUID): WorkSpec {
        val workManagerImpl = WorkManagerImpl.getInstance(context)
        return requireNotNull(workManagerImpl.workDatabase.workSpecDao().getWorkSpec(workId.toString()))
    }
}