Merge changes Icd1cbc6a,I487ced4c into main
* changes:
[SB][Screen Chips] Implement the screen record chip flow.
[SB][Screen Chips] Move OngoingActivityChipModel to domain layer.
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 e85df0e..c57cf69 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 @@
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 70362c8..c3d37fb 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
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/chips/domain/model/OngoingActivityChipModel.kt
index e63713b..c753918 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 6f16969..bff5686 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 47b2b03..208eb50 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 @@
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 0000000..25efaf1
--- /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 fa2b343..1260f07 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.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 @@
@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 @@
@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 @@
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 @@
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 @@
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 cd08274..90d459b 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 ffbaa7f..9e02df9 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() }