diff options
2 files changed, 170 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/RefreshUsersScheduler.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/RefreshUsersScheduler.kt new file mode 100644 index 000000000000..8f36821a955e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/RefreshUsersScheduler.kt @@ -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 + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt new file mode 100644 index 000000000000..593ce1f0a2f5 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/RefreshUsersSchedulerTest.kt @@ -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 + } +} |