Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt +15 −73 Original line number Diff line number Diff line Loading @@ -25,11 +25,8 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.screenrecord.RecordingController import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.screenRecordRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf Loading @@ -37,7 +34,6 @@ import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.verify @OptIn(ExperimentalCoroutinesApi::class) @SmallTest Loading @@ -46,13 +42,13 @@ import org.mockito.Mockito.verify class ScreenRecordTileDataInteractorTest : SysuiTestCase() { private val kosmos = Kosmos() private val testScope = kosmos.testScope private val controller = mock<RecordingController>() private val screenRecordRepo = kosmos.screenRecordRepository private val underTest: ScreenRecordTileDataInteractor = ScreenRecordTileDataInteractor(testScope.testScheduler, controller) ScreenRecordTileDataInteractor(screenRecordRepo) private val isRecording = ScreenRecordTileModel.Recording private val isDoingNothing = ScreenRecordTileModel.DoingNothing private val isStarting0 = ScreenRecordTileModel.Starting(0) private val isRecording = ScreenRecordModel.Recording private val isDoingNothing = ScreenRecordModel.DoingNothing private val isStarting0 = ScreenRecordModel.Starting(0) @Test fun isAvailable_returnsTrue() = runTest { Loading @@ -62,87 +58,33 @@ class ScreenRecordTileDataInteractorTest : SysuiTestCase() { } @Test fun dataMatchesController() = fun dataMatchesRepo() = testScope.runTest { whenever(controller.isRecording).thenReturn(false) whenever(controller.isStarting).thenReturn(false) val callbackCaptor = argumentCaptor<RecordingController.RecordingStateChangeCallback>() val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() verify(controller).addCallback(callbackCaptor.capture()) val callback = callbackCaptor.value assertThat(lastModel).isEqualTo(isDoingNothing) val expectedModelStartingIn1 = ScreenRecordTileModel.Starting(1) callback.onCountdown(1) val expectedModelStartingIn1 = ScreenRecordModel.Starting(1) screenRecordRepo.screenRecordState.value = expectedModelStartingIn1 assertThat(lastModel).isEqualTo(expectedModelStartingIn1) val expectedModelStartingIn0 = isStarting0 callback.onCountdown(0) assertThat(lastModel).isEqualTo(expectedModelStartingIn0) screenRecordRepo.screenRecordState.value = isStarting0 assertThat(lastModel).isEqualTo(isStarting0) callback.onCountdownEnd() screenRecordRepo.screenRecordState.value = isDoingNothing assertThat(lastModel).isEqualTo(isDoingNothing) callback.onRecordingStart() screenRecordRepo.screenRecordState.value = isRecording assertThat(lastModel).isEqualTo(isRecording) callback.onRecordingEnd() screenRecordRepo.screenRecordState.value = isDoingNothing assertThat(lastModel).isEqualTo(isDoingNothing) } @Test fun data_whenRecording_matchesController() = testScope.runTest { whenever(controller.isRecording).thenReturn(true) whenever(controller.isStarting).thenReturn(false) val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(lastModel).isEqualTo(isRecording) } @Test fun data_whenStarting_matchesController() = testScope.runTest { whenever(controller.isRecording).thenReturn(false) whenever(controller.isStarting).thenReturn(true) val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(lastModel).isEqualTo(isStarting0) } @Test fun data_whenRecordingAndStarting_matchesControllerRecording() = testScope.runTest { whenever(controller.isRecording).thenReturn(true) whenever(controller.isStarting).thenReturn(true) val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(lastModel).isEqualTo(isRecording) } private companion object { val TEST_USER = UserHandle.of(1)!! } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt +5 −5 Original line number Diff line number Diff line Loading @@ -33,8 +33,8 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.plugins.activityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.statusbar.phone.KeyguardDismissUtil import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor Loading Loading @@ -89,7 +89,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleClick_whenStarting_cancelCountdown() = runTest { val startingModel = ScreenRecordTileModel.Starting(0) val startingModel = ScreenRecordModel.Starting(0) underTest.handleInput(QSTileInputTestKtx.click(startingModel)) Loading @@ -98,7 +98,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleClick_whenRecording_stopRecording() = runTest { val recordingModel = ScreenRecordTileModel.Recording val recordingModel = ScreenRecordModel.Recording underTest.handleInput(QSTileInputTestKtx.click(recordingModel)) Loading @@ -107,7 +107,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleClick_whenDoingNothing_createDialogDismissPanelShowDialog() = runTest { val recordingModel = ScreenRecordTileModel.DoingNothing val recordingModel = ScreenRecordModel.DoingNothing underTest.handleInput(QSTileInputTestKtx.click(recordingModel)) val onStartRecordingClickedCaptor = argumentCaptor<Runnable>() Loading Loading @@ -143,7 +143,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { kosmos.fakeKeyguardRepository.setKeyguardShowing(false) val recordingModel = ScreenRecordTileModel.DoingNothing val recordingModel = ScreenRecordModel.DoingNothing underTest.handleInput( QSTileInputTestKtx.click(recordingModel, UserHandle.CURRENT, expandable) Loading packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt +4 −4 Original line number Diff line number Diff line Loading @@ -25,11 +25,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.ScreenRecordTileMapper import com.android.systemui.qs.tiles.impl.screenrecord.qsScreenRecordTileConfig import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.screenrecord.data.model.ScreenRecordModel import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -58,7 +58,7 @@ class ScreenRecordTileMapperTest : SysuiTestCase() { @Test fun activeStateMatchesRecordingDataModel() { val inputModel = ScreenRecordTileModel.Recording val inputModel = ScreenRecordModel.Recording val outputState = mapper.map(config, inputModel) Loading @@ -74,7 +74,7 @@ class ScreenRecordTileMapperTest : SysuiTestCase() { @Test fun activeStateMatchesStartingDataModel() { val timeLeft = 0L val inputModel = ScreenRecordTileModel.Starting(timeLeft) val inputModel = ScreenRecordModel.Starting(timeLeft) val outputState = mapper.map(config, inputModel) Loading @@ -89,7 +89,7 @@ class ScreenRecordTileMapperTest : SysuiTestCase() { @Test fun inactiveStateMatchesDisabledDataModel() { val inputModel = ScreenRecordTileModel.DoingNothing val inputModel = ScreenRecordModel.DoingNothing val outputState = mapper.map(config, inputModel) Loading packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt +6 −51 Original line number Diff line number Diff line Loading @@ -17,70 +17,25 @@ package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor import android.os.UserHandle import com.android.systemui.common.coroutine.ConflatedCallbackFlow import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.onStart /** Observes screen record state changes providing the [ScreenRecordTileModel]. */ /** Observes screen record state changes providing the [ScreenRecordModel]. */ class ScreenRecordTileDataInteractor @Inject constructor( @Background private val bgCoroutineContext: CoroutineContext, private val recordingController: RecordingController, ) : QSTileDataInteractor<ScreenRecordTileModel> { private val screenRecordRepository: ScreenRecordRepository, ) : QSTileDataInteractor<ScreenRecordModel> { override fun tileData( user: UserHandle, triggers: Flow<DataUpdateTrigger> ): Flow<ScreenRecordTileModel> = ConflatedCallbackFlow.conflatedCallbackFlow { val callback = object : RecordingController.RecordingStateChangeCallback { override fun onRecordingStart() { trySend(ScreenRecordTileModel.Recording) } override fun onRecordingEnd() { trySend(ScreenRecordTileModel.DoingNothing) } override fun onCountdown(millisUntilFinished: Long) { trySend(ScreenRecordTileModel.Starting(millisUntilFinished)) } override fun onCountdownEnd() { if ( !recordingController.isRecording && !recordingController.isStarting ) { // The tile was in Starting state and got canceled before recording trySend(ScreenRecordTileModel.DoingNothing) } } } recordingController.addCallback(callback) awaitClose { recordingController.removeCallback(callback) } } .onStart { emit(generateModel()) } .distinctUntilChanged() .flowOn(bgCoroutineContext) ): Flow<ScreenRecordModel> = screenRecordRepository.screenRecordState override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) private fun generateModel(): ScreenRecordTileModel { if (recordingController.isRecording) { return ScreenRecordTileModel.Recording } else if (recordingController.isStarting) { return ScreenRecordTileModel.Starting(0) } else { return ScreenRecordTileModel.DoingNothing } } } packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt +6 −6 Original line number Diff line number Diff line Loading @@ -32,9 +32,9 @@ import com.android.systemui.plugins.ActivityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileInput import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.statusbar.phone.KeyguardDismissUtil import javax.inject.Inject import kotlin.coroutines.CoroutineContext Loading @@ -55,19 +55,19 @@ constructor( private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, private val featureFlags: FeatureFlagsClassic, private val activityStarter: ActivityStarter, ) : QSTileUserActionInteractor<ScreenRecordTileModel> { override suspend fun handleInput(input: QSTileInput<ScreenRecordTileModel>): Unit = ) : QSTileUserActionInteractor<ScreenRecordModel> { override suspend fun handleInput(input: QSTileInput<ScreenRecordModel>): Unit = with(input) { when (action) { is QSTileUserAction.Click -> { when (data) { is ScreenRecordTileModel.Starting -> { is ScreenRecordModel.Starting -> { Log.d(TAG, "Cancelling countdown") withContext(backgroundContext) { recordingController.cancelCountdown() } } is ScreenRecordTileModel.Recording -> is ScreenRecordModel.Recording -> withContext(backgroundContext) { recordingController.stopRecording() } is ScreenRecordTileModel.DoingNothing -> is ScreenRecordModel.DoingNothing -> withContext(mainContext) { showPrompt(action.expandable, user.identifier) } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt +15 −73 Original line number Diff line number Diff line Loading @@ -25,11 +25,8 @@ import com.android.systemui.coroutines.collectLastValue import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.testScope import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.screenrecord.RecordingController import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.screenRecordRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf Loading @@ -37,7 +34,6 @@ import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.verify @OptIn(ExperimentalCoroutinesApi::class) @SmallTest Loading @@ -46,13 +42,13 @@ import org.mockito.Mockito.verify class ScreenRecordTileDataInteractorTest : SysuiTestCase() { private val kosmos = Kosmos() private val testScope = kosmos.testScope private val controller = mock<RecordingController>() private val screenRecordRepo = kosmos.screenRecordRepository private val underTest: ScreenRecordTileDataInteractor = ScreenRecordTileDataInteractor(testScope.testScheduler, controller) ScreenRecordTileDataInteractor(screenRecordRepo) private val isRecording = ScreenRecordTileModel.Recording private val isDoingNothing = ScreenRecordTileModel.DoingNothing private val isStarting0 = ScreenRecordTileModel.Starting(0) private val isRecording = ScreenRecordModel.Recording private val isDoingNothing = ScreenRecordModel.DoingNothing private val isStarting0 = ScreenRecordModel.Starting(0) @Test fun isAvailable_returnsTrue() = runTest { Loading @@ -62,87 +58,33 @@ class ScreenRecordTileDataInteractorTest : SysuiTestCase() { } @Test fun dataMatchesController() = fun dataMatchesRepo() = testScope.runTest { whenever(controller.isRecording).thenReturn(false) whenever(controller.isStarting).thenReturn(false) val callbackCaptor = argumentCaptor<RecordingController.RecordingStateChangeCallback>() val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() verify(controller).addCallback(callbackCaptor.capture()) val callback = callbackCaptor.value assertThat(lastModel).isEqualTo(isDoingNothing) val expectedModelStartingIn1 = ScreenRecordTileModel.Starting(1) callback.onCountdown(1) val expectedModelStartingIn1 = ScreenRecordModel.Starting(1) screenRecordRepo.screenRecordState.value = expectedModelStartingIn1 assertThat(lastModel).isEqualTo(expectedModelStartingIn1) val expectedModelStartingIn0 = isStarting0 callback.onCountdown(0) assertThat(lastModel).isEqualTo(expectedModelStartingIn0) screenRecordRepo.screenRecordState.value = isStarting0 assertThat(lastModel).isEqualTo(isStarting0) callback.onCountdownEnd() screenRecordRepo.screenRecordState.value = isDoingNothing assertThat(lastModel).isEqualTo(isDoingNothing) callback.onRecordingStart() screenRecordRepo.screenRecordState.value = isRecording assertThat(lastModel).isEqualTo(isRecording) callback.onRecordingEnd() screenRecordRepo.screenRecordState.value = isDoingNothing assertThat(lastModel).isEqualTo(isDoingNothing) } @Test fun data_whenRecording_matchesController() = testScope.runTest { whenever(controller.isRecording).thenReturn(true) whenever(controller.isStarting).thenReturn(false) val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(lastModel).isEqualTo(isRecording) } @Test fun data_whenStarting_matchesController() = testScope.runTest { whenever(controller.isRecording).thenReturn(false) whenever(controller.isStarting).thenReturn(true) val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(lastModel).isEqualTo(isStarting0) } @Test fun data_whenRecordingAndStarting_matchesControllerRecording() = testScope.runTest { whenever(controller.isRecording).thenReturn(true) whenever(controller.isStarting).thenReturn(true) val lastModel by collectLastValue( underTest.tileData(TEST_USER, flowOf(DataUpdateTrigger.InitialRequest)) ) runCurrent() assertThat(lastModel).isEqualTo(isRecording) } private companion object { val TEST_USER = UserHandle.of(1)!! } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt +5 −5 Original line number Diff line number Diff line Loading @@ -33,8 +33,8 @@ import com.android.systemui.plugins.ActivityStarter.OnDismissAction import com.android.systemui.plugins.activityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.statusbar.phone.KeyguardDismissUtil import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.argumentCaptor Loading Loading @@ -89,7 +89,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleClick_whenStarting_cancelCountdown() = runTest { val startingModel = ScreenRecordTileModel.Starting(0) val startingModel = ScreenRecordModel.Starting(0) underTest.handleInput(QSTileInputTestKtx.click(startingModel)) Loading @@ -98,7 +98,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleClick_whenRecording_stopRecording() = runTest { val recordingModel = ScreenRecordTileModel.Recording val recordingModel = ScreenRecordModel.Recording underTest.handleInput(QSTileInputTestKtx.click(recordingModel)) Loading @@ -107,7 +107,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { @Test fun handleClick_whenDoingNothing_createDialogDismissPanelShowDialog() = runTest { val recordingModel = ScreenRecordTileModel.DoingNothing val recordingModel = ScreenRecordModel.DoingNothing underTest.handleInput(QSTileInputTestKtx.click(recordingModel)) val onStartRecordingClickedCaptor = argumentCaptor<Runnable>() Loading Loading @@ -143,7 +143,7 @@ class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() { kosmos.fakeKeyguardRepository.setKeyguardShowing(false) val recordingModel = ScreenRecordTileModel.DoingNothing val recordingModel = ScreenRecordModel.DoingNothing underTest.handleInput( QSTileInputTestKtx.click(recordingModel, UserHandle.CURRENT, expandable) Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt +4 −4 Original line number Diff line number Diff line Loading @@ -25,11 +25,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.common.shared.model.Icon import com.android.systemui.kosmos.Kosmos import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.ScreenRecordTileMapper import com.android.systemui.qs.tiles.impl.screenrecord.qsScreenRecordTileConfig import com.android.systemui.qs.tiles.viewmodel.QSTileState import com.android.systemui.res.R import com.android.systemui.screenrecord.data.model.ScreenRecordModel import org.junit.Before import org.junit.Test import org.junit.runner.RunWith Loading Loading @@ -58,7 +58,7 @@ class ScreenRecordTileMapperTest : SysuiTestCase() { @Test fun activeStateMatchesRecordingDataModel() { val inputModel = ScreenRecordTileModel.Recording val inputModel = ScreenRecordModel.Recording val outputState = mapper.map(config, inputModel) Loading @@ -74,7 +74,7 @@ class ScreenRecordTileMapperTest : SysuiTestCase() { @Test fun activeStateMatchesStartingDataModel() { val timeLeft = 0L val inputModel = ScreenRecordTileModel.Starting(timeLeft) val inputModel = ScreenRecordModel.Starting(timeLeft) val outputState = mapper.map(config, inputModel) Loading @@ -89,7 +89,7 @@ class ScreenRecordTileMapperTest : SysuiTestCase() { @Test fun inactiveStateMatchesDisabledDataModel() { val inputModel = ScreenRecordTileModel.DoingNothing val inputModel = ScreenRecordModel.DoingNothing val outputState = mapper.map(config, inputModel) Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt +6 −51 Original line number Diff line number Diff line Loading @@ -17,70 +17,25 @@ package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor import android.os.UserHandle import com.android.systemui.common.coroutine.ConflatedCallbackFlow import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository import javax.inject.Inject import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.onStart /** Observes screen record state changes providing the [ScreenRecordTileModel]. */ /** Observes screen record state changes providing the [ScreenRecordModel]. */ class ScreenRecordTileDataInteractor @Inject constructor( @Background private val bgCoroutineContext: CoroutineContext, private val recordingController: RecordingController, ) : QSTileDataInteractor<ScreenRecordTileModel> { private val screenRecordRepository: ScreenRecordRepository, ) : QSTileDataInteractor<ScreenRecordModel> { override fun tileData( user: UserHandle, triggers: Flow<DataUpdateTrigger> ): Flow<ScreenRecordTileModel> = ConflatedCallbackFlow.conflatedCallbackFlow { val callback = object : RecordingController.RecordingStateChangeCallback { override fun onRecordingStart() { trySend(ScreenRecordTileModel.Recording) } override fun onRecordingEnd() { trySend(ScreenRecordTileModel.DoingNothing) } override fun onCountdown(millisUntilFinished: Long) { trySend(ScreenRecordTileModel.Starting(millisUntilFinished)) } override fun onCountdownEnd() { if ( !recordingController.isRecording && !recordingController.isStarting ) { // The tile was in Starting state and got canceled before recording trySend(ScreenRecordTileModel.DoingNothing) } } } recordingController.addCallback(callback) awaitClose { recordingController.removeCallback(callback) } } .onStart { emit(generateModel()) } .distinctUntilChanged() .flowOn(bgCoroutineContext) ): Flow<ScreenRecordModel> = screenRecordRepository.screenRecordState override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true) private fun generateModel(): ScreenRecordTileModel { if (recordingController.isRecording) { return ScreenRecordTileModel.Recording } else if (recordingController.isStarting) { return ScreenRecordTileModel.Starting(0) } else { return ScreenRecordTileModel.DoingNothing } } }
packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt +6 −6 Original line number Diff line number Diff line Loading @@ -32,9 +32,9 @@ import com.android.systemui.plugins.ActivityStarter import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor import com.android.systemui.qs.tiles.base.interactor.QSTileInput import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor import com.android.systemui.qs.tiles.impl.screenrecord.domain.model.ScreenRecordTileModel import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction import com.android.systemui.screenrecord.RecordingController import com.android.systemui.screenrecord.data.model.ScreenRecordModel import com.android.systemui.statusbar.phone.KeyguardDismissUtil import javax.inject.Inject import kotlin.coroutines.CoroutineContext Loading @@ -55,19 +55,19 @@ constructor( private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger, private val featureFlags: FeatureFlagsClassic, private val activityStarter: ActivityStarter, ) : QSTileUserActionInteractor<ScreenRecordTileModel> { override suspend fun handleInput(input: QSTileInput<ScreenRecordTileModel>): Unit = ) : QSTileUserActionInteractor<ScreenRecordModel> { override suspend fun handleInput(input: QSTileInput<ScreenRecordModel>): Unit = with(input) { when (action) { is QSTileUserAction.Click -> { when (data) { is ScreenRecordTileModel.Starting -> { is ScreenRecordModel.Starting -> { Log.d(TAG, "Cancelling countdown") withContext(backgroundContext) { recordingController.cancelCountdown() } } is ScreenRecordTileModel.Recording -> is ScreenRecordModel.Recording -> withContext(backgroundContext) { recordingController.stopRecording() } is ScreenRecordTileModel.DoingNothing -> is ScreenRecordModel.DoingNothing -> withContext(mainContext) { showPrompt(action.expandable, user.identifier) } Loading