diff options
| author | 2024-05-24 20:34:39 +0000 | |
|---|---|---|
| committer | 2024-05-24 20:34:39 +0000 | |
| commit | cd92b5dc6309a213bb2ab91c033dc7e3e591f3b7 (patch) | |
| tree | eaf5913c46e0a7ef3e9abeac79030354081f37a0 | |
| parent | d7a5e6a8abdfca781200d2b9b704fc656517e5c7 (diff) | |
| parent | 764e8540729dc0407a92d094125ec7db67f49d1f (diff) | |
Merge changes Icd1cbc6a,I487ced4c into main
* changes:
[SB][Screen Chips] Implement the screen record chip flow.
[SB][Screen Chips] Move OngoingActivityChipModel to domain layer.
9 files changed, 173 insertions, 51 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt index e85df0eb9a70..c57cf69a5d79 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/domain/interactor/CallChipInteractor.kt @@ -18,7 +18,7 @@ package com.android.systemui.statusbar.chips.call.domain.interactor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor -import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel import javax.inject.Inject import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt index 70362c8527f4..c3d37fb3d952 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/interactor/OngoingActivityChipInteractor.kt @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.chips.domain.interactor -import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel import kotlinx.coroutines.flow.StateFlow /** Interface for an interactor that knows the state of a single type of ongoing activity chip. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/model/OngoingActivityChipModel.kt index e63713bf1602..c7539181fe31 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/model/OngoingActivityChipModel.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.chips.ui.model +package com.android.systemui.statusbar.chips.domain.model import android.view.View import com.android.systemui.common.shared.model.Icon diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt index 6f16969b1bb6..bff5686641c2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractor.kt @@ -16,17 +16,51 @@ package com.android.systemui.statusbar.chips.screenrecord.domain.interactor +import com.android.systemui.common.shared.model.Icon import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.res.R +import com.android.systemui.screenrecord.data.model.ScreenRecordModel +import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository import com.android.systemui.statusbar.chips.domain.interactor.OngoingActivityChipInteractor +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel +import com.android.systemui.util.time.SystemClock import javax.inject.Inject -import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn /** Interactor for the screen recording chip shown in the status bar. */ @SysUISingleton -open class ScreenRecordChipInteractor @Inject constructor() : OngoingActivityChipInteractor { - // TODO(b/332662551): Implement this flow. +open class ScreenRecordChipInteractor +@Inject +constructor( + @Application scope: CoroutineScope, + screenRecordRepository: ScreenRecordRepository, + val systemClock: SystemClock, +) : OngoingActivityChipInteractor { override val chip: StateFlow<OngoingActivityChipModel> = - MutableStateFlow(OngoingActivityChipModel.Hidden) + screenRecordRepository.screenRecordState + .map { state -> + when (state) { + is ScreenRecordModel.DoingNothing, + // TODO(b/332662551): Implement the 3-2-1 countdown chip. + is ScreenRecordModel.Starting -> OngoingActivityChipModel.Hidden + is ScreenRecordModel.Recording -> + OngoingActivityChipModel.Shown( + // TODO(b/332662551): Also provide a content description. + icon = + Icon.Resource( + R.drawable.stat_sys_screen_record, + contentDescription = null + ), + startTimeMs = systemClock.elapsedRealtime() + ) { + // TODO(b/332662551): Implement the pause dialog. + } + } + } + .stateIn(scope, SharingStarted.WhileSubscribed(), OngoingActivityChipModel.Hidden) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt index 47b2b0346d4a..208eb50487e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModel.kt @@ -19,8 +19,8 @@ package com.android.systemui.statusbar.chips.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor -import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel import javax.inject.Inject import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt new file mode 100644 index 000000000000..25efaf10fce7 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/screenrecord/domain/interactor/ScreenRecordChipInteractorTest.kt @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 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.statusbar.chips.screenrecord.domain.interactor + +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.common.shared.model.Icon +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.testScope +import com.android.systemui.res.R +import com.android.systemui.screenrecord.data.model.ScreenRecordModel +import com.android.systemui.screenrecord.data.repository.screenRecordRepository +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel +import com.android.systemui.statusbar.chips.ui.viewmodel.screenRecordChipInteractor +import com.android.systemui.util.time.fakeSystemClock +import com.google.common.truth.Truth.assertThat +import kotlin.test.Test +import kotlinx.coroutines.test.runTest + +@SmallTest +class ScreenRecordChipInteractorTest : SysuiTestCase() { + private val kosmos = Kosmos() + private val testScope = kosmos.testScope + private val screenRecordRepo = kosmos.screenRecordRepository + private val systemClock = kosmos.fakeSystemClock + + private val underTest = kosmos.screenRecordChipInteractor + + @Test + fun chip_doingNothingState_isHidden() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + screenRecordRepo.screenRecordState.value = ScreenRecordModel.DoingNothing + + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java) + } + + @Test + fun chip_startingState_isHidden() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Starting(400) + + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java) + } + + @Test + fun chip_recordingState_isShownWithIcon() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java) + val icon = (latest as OngoingActivityChipModel.Shown).icon + assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.stat_sys_screen_record) + } + + @Test + fun chip_timeResetsOnEachNewRecording() = + testScope.runTest { + val latest by collectLastValue(underTest.chip) + + systemClock.setElapsedRealtime(1234) + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java) + assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(1234) + + screenRecordRepo.screenRecordState.value = ScreenRecordModel.DoingNothing + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Hidden::class.java) + + systemClock.setElapsedRealtime(5678) + screenRecordRepo.screenRecordState.value = ScreenRecordModel.Recording + + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java) + assertThat((latest as OngoingActivityChipModel.Shown).startTimeMs).isEqualTo(5678) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt index fa2b343c3f3d..1260f07d0ba1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelTest.kt @@ -24,7 +24,9 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.res.R -import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.screenrecord.data.model.ScreenRecordModel +import com.android.systemui.screenrecord.data.repository.screenRecordRepository +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.test.runTest import org.junit.Test @@ -38,7 +40,7 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { @Test fun chip_allHidden_hidden() = kosmos.testScope.runTest { - kosmos.screenRecordChipInteractor.chip.value = OngoingActivityChipModel.Hidden + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.DoingNothing kosmos.callChipInteractor.chip.value = OngoingActivityChipModel.Hidden val latest by collectLastValue(underTest.chip) @@ -49,28 +51,18 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { @Test fun chip_screenRecordShow_restHidden_screenRecordShown() = kosmos.testScope.runTest { - val screenRecordChip = - OngoingActivityChipModel.Shown( - Icon.Resource(R.drawable.ic_cake, ContentDescription.Loaded("icon")), - startTimeMs = 500L, - ) {} - kosmos.screenRecordChipInteractor.chip.value = screenRecordChip + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording kosmos.callChipInteractor.chip.value = OngoingActivityChipModel.Hidden val latest by collectLastValue(underTest.chip) - assertThat(latest).isEqualTo(screenRecordChip) + assertIsScreenRecordChip(latest) } @Test fun chip_screenRecordShowAndCallShow_screenRecordShown() = kosmos.testScope.runTest { - val screenRecordChip = - OngoingActivityChipModel.Shown( - Icon.Resource(R.drawable.ic_cake, ContentDescription.Loaded("icon")), - startTimeMs = 500L, - ) {} - kosmos.screenRecordChipInteractor.chip.value = screenRecordChip + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording val callChip = OngoingActivityChipModel.Shown( @@ -81,13 +73,13 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { val latest by collectLastValue(underTest.chip) - assertThat(latest).isEqualTo(screenRecordChip) + assertIsScreenRecordChip(latest) } @Test fun chip_screenRecordHideAndCallShown_callShown() = kosmos.testScope.runTest { - kosmos.screenRecordChipInteractor.chip.value = OngoingActivityChipModel.Hidden + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.DoingNothing val callChip = OngoingActivityChipModel.Shown( @@ -111,34 +103,24 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { startTimeMs = 600L, ) {} kosmos.callChipInteractor.chip.value = callChip - kosmos.screenRecordChipInteractor.chip.value = OngoingActivityChipModel.Hidden + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.DoingNothing val latest by collectLastValue(underTest.chip) assertThat(latest).isEqualTo(callChip) // WHEN the higher priority screen record chip is added - val screenRecordChip = - OngoingActivityChipModel.Shown( - Icon.Resource(R.drawable.ic_cake, ContentDescription.Loaded("icon")), - startTimeMs = 500L, - ) {} - kosmos.screenRecordChipInteractor.chip.value = screenRecordChip + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording // THEN the higher priority screen record chip is used - assertThat(latest).isEqualTo(screenRecordChip) + assertIsScreenRecordChip(latest) } @Test fun chip_highestPriorityChipRemoved_showsNextPriorityChip() = kosmos.testScope.runTest { // Start with both the higher priority screen record chip and lower priority call chip - val screenRecordChip = - OngoingActivityChipModel.Shown( - Icon.Resource(R.drawable.ic_cake, ContentDescription.Loaded("icon")), - startTimeMs = 500L, - ) {} - kosmos.screenRecordChipInteractor.chip.value = screenRecordChip + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording val callChip = OngoingActivityChipModel.Shown( @@ -149,12 +131,18 @@ class OngoingActivityChipsViewModelTest : SysuiTestCase() { val latest by collectLastValue(underTest.chip) - assertThat(latest).isEqualTo(screenRecordChip) + assertIsScreenRecordChip(latest) // WHEN the higher priority screen record is removed - kosmos.screenRecordChipInteractor.chip.value = OngoingActivityChipModel.Hidden + kosmos.screenRecordRepository.screenRecordState.value = ScreenRecordModel.DoingNothing // THEN the lower priority call is used assertThat(latest).isEqualTo(callChip) } + + private fun assertIsScreenRecordChip(latest: OngoingActivityChipModel?) { + assertThat(latest).isInstanceOf(OngoingActivityChipModel.Shown::class.java) + val icon = (latest as OngoingActivityChipModel.Shown).icon + assertThat((icon as Icon.Resource).res).isEqualTo(R.drawable.stat_sys_screen_record) + } } diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/FakeOngoingActivityChipInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/FakeOngoingActivityChipInteractor.kt index cd08274c5f98..90d459b5d3c8 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/FakeOngoingActivityChipInteractor.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/FakeOngoingActivityChipInteractor.kt @@ -17,15 +17,9 @@ package com.android.systemui.statusbar.chips.ui.viewmodel import com.android.systemui.statusbar.chips.call.domain.interactor.CallChipInteractor -import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor -import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel +import com.android.systemui.statusbar.chips.domain.model.OngoingActivityChipModel import kotlinx.coroutines.flow.MutableStateFlow -class FakeScreenRecordChipInteractor : ScreenRecordChipInteractor() { - override val chip: MutableStateFlow<OngoingActivityChipModel> = - MutableStateFlow(OngoingActivityChipModel.Hidden) -} - class FakeCallChipInteractor : CallChipInteractor() { override val chip: MutableStateFlow<OngoingActivityChipModel> = MutableStateFlow(OngoingActivityChipModel.Hidden) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt index ffbaa7ff3528..9e02df9c3f41 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/chips/ui/viewmodel/OngoingActivityChipsViewModelKosmos.kt @@ -17,10 +17,20 @@ package com.android.systemui.statusbar.chips.ui.viewmodel import com.android.systemui.kosmos.Kosmos +import com.android.systemui.kosmos.applicationCoroutineScope import com.android.systemui.kosmos.testScope +import com.android.systemui.screenrecord.data.repository.screenRecordRepository +import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.ScreenRecordChipInteractor +import com.android.systemui.util.time.fakeSystemClock -val Kosmos.screenRecordChipInteractor: FakeScreenRecordChipInteractor by - Kosmos.Fixture { FakeScreenRecordChipInteractor() } +val Kosmos.screenRecordChipInteractor: ScreenRecordChipInteractor by + Kosmos.Fixture { + ScreenRecordChipInteractor( + scope = applicationCoroutineScope, + screenRecordRepository = screenRecordRepository, + systemClock = fakeSystemClock, + ) + } val Kosmos.callChipInteractor: FakeCallChipInteractor by Kosmos.Fixture { FakeCallChipInteractor() } |