RefreshScheduler.

A piece of business logic used by interactors (in next CLs) that can
pause, unpause, and schedule "refresh users" logic to happen.

Bug: 246631653
Test: Included in CL
Change-Id: I18d51923bfaad7a06fc6cb372f5139f0fff65411
This commit is contained in:
Alejandro Nijamkin
2022-09-28 09:51:39 -07:00
parent 32b5486aa6
commit 0fd4ee1280
2 changed files with 170 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.user.domain.interactor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.user.data.repository.UserRepository
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
/** Encapsulates logic for pausing, unpausing, and scheduling a delayed job. */
@SysUISingleton
class RefreshUsersScheduler
@Inject
constructor(
@Application private val applicationScope: CoroutineScope,
@Main private val mainDispatcher: CoroutineDispatcher,
private val repository: UserRepository,
) {
private var scheduledUnpauseJob: Job? = null
private var isPaused = false
fun pause() {
applicationScope.launch(mainDispatcher) {
isPaused = true
scheduledUnpauseJob?.cancel()
scheduledUnpauseJob =
applicationScope.launch {
delay(PAUSE_REFRESH_USERS_TIMEOUT_MS)
unpauseAndRefresh()
}
}
}
fun unpauseAndRefresh() {
applicationScope.launch(mainDispatcher) {
isPaused = false
refreshIfNotPaused()
}
}
fun refreshIfNotPaused() {
applicationScope.launch(mainDispatcher) {
if (isPaused) {
return@launch
}
repository.refreshUsers()
}
}
companion object {
private const val PAUSE_REFRESH_USERS_TIMEOUT_MS = 3000L
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.user.domain.interactor
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.user.data.repository.FakeUserRepository
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(JUnit4::class)
class RefreshUsersSchedulerTest : SysuiTestCase() {
private lateinit var underTest: RefreshUsersScheduler
private lateinit var repository: FakeUserRepository
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
repository = FakeUserRepository()
}
@Test
fun `pause - prevents the next refresh from happening`() =
runBlocking(IMMEDIATE) {
underTest =
RefreshUsersScheduler(
applicationScope = this,
mainDispatcher = IMMEDIATE,
repository = repository,
)
underTest.pause()
underTest.refreshIfNotPaused()
assertThat(repository.refreshUsersCallCount).isEqualTo(0)
}
@Test
fun `unpauseAndRefresh - forces the refresh even when paused`() =
runBlocking(IMMEDIATE) {
underTest =
RefreshUsersScheduler(
applicationScope = this,
mainDispatcher = IMMEDIATE,
repository = repository,
)
underTest.pause()
underTest.unpauseAndRefresh()
assertThat(repository.refreshUsersCallCount).isEqualTo(1)
}
@Test
fun `refreshIfNotPaused - refreshes when not paused`() =
runBlocking(IMMEDIATE) {
underTest =
RefreshUsersScheduler(
applicationScope = this,
mainDispatcher = IMMEDIATE,
repository = repository,
)
underTest.refreshIfNotPaused()
assertThat(repository.refreshUsersCallCount).isEqualTo(1)
}
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
}
}