Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21465c3a authored by Chris Göllner's avatar Chris Göllner
Browse files

PSS Task Switcher: Improve unit tests - Use real repositories

- Use real repositories and interactor in all tests
- The only fake parts are now the data sources: ActivityTaskManager and
  MediaProjectionManager.
  To make it easier to interact with them, there are now fake versions
  of those.

Bug: 286201261
Test: All unit tests under mediaprojection/taskswitcher/
Change-Id: I9a3732e26d9206f895cfe9f88a4329d67219c389
parent 0b73a074
Loading
Loading
Loading
Loading
+71 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.mediaprojection.taskswitcher.data.repository

import android.media.projection.MediaProjectionInfo
import android.media.projection.MediaProjectionManager
import android.os.Binder
import android.os.IBinder
import android.os.UserHandle
import android.view.ContentRecordingSession
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever

class FakeMediaProjectionManager {

    val mediaProjectionManager = mock<MediaProjectionManager>()

    private val callbacks = mutableListOf<MediaProjectionManager.Callback>()

    init {
        whenever(mediaProjectionManager.addCallback(any(), any())).thenAnswer {
            callbacks += it.arguments[0] as MediaProjectionManager.Callback
            return@thenAnswer Unit
        }
        whenever(mediaProjectionManager.removeCallback(any())).thenAnswer {
            callbacks -= it.arguments[0] as MediaProjectionManager.Callback
            return@thenAnswer Unit
        }
    }

    fun dispatchOnStart(info: MediaProjectionInfo = DEFAULT_INFO) {
        callbacks.forEach { it.onStart(info) }
    }

    fun dispatchOnStop(info: MediaProjectionInfo = DEFAULT_INFO) {
        callbacks.forEach { it.onStop(info) }
    }

    fun dispatchOnSessionSet(
        info: MediaProjectionInfo = DEFAULT_INFO,
        session: ContentRecordingSession?
    ) {
        callbacks.forEach { it.onRecordingSessionSet(info, session) }
    }

    companion object {
        fun createDisplaySession(): ContentRecordingSession =
            ContentRecordingSession.createDisplaySession(/* displayToMirror = */ 123)
        fun createSingleTaskSession(token: IBinder = Binder()): ContentRecordingSession =
            ContentRecordingSession.createTaskSession(token)

        private const val DEFAULT_PACKAGE_NAME = "com.media.projection.test"
        private val DEFAULT_USER_HANDLE = UserHandle.getUserHandleForUid(UserHandle.myUserId())
        private val DEFAULT_INFO = MediaProjectionInfo(DEFAULT_PACKAGE_NAME, DEFAULT_USER_HANDLE)
    }
}
+0 −42
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.mediaprojection.taskswitcher.data.repository

import android.app.TaskInfo
import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

class FakeMediaProjectionRepository : MediaProjectionRepository {

    private val state = MutableStateFlow<MediaProjectionState>(MediaProjectionState.NotProjecting)

    fun switchProjectedTask(newTask: TaskInfo) {
        state.value = MediaProjectionState.SingleTask(newTask)
    }

    override val mediaProjectionState: Flow<MediaProjectionState> = state.asStateFlow()

    fun projectEntireScreen() {
        state.value = MediaProjectionState.EntireScreen
    }

    fun stopProjecting() {
        state.value = MediaProjectionState.NotProjecting
    }
}
+0 −68
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2023 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.mediaprojection.taskswitcher.data.repository

import android.app.ActivityManager.RunningTaskInfo
import android.content.Intent
import android.os.IBinder
import android.window.IWindowContainerToken
import android.window.WindowContainerToken
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow

class FakeTasksRepository : TasksRepository {

    private val _foregroundTask = MutableStateFlow(DEFAULT_TASK)

    override val foregroundTask: Flow<RunningTaskInfo> = _foregroundTask.asStateFlow()

    private val runningTasks = mutableListOf(DEFAULT_TASK)

    override suspend fun findRunningTaskFromWindowContainerToken(
        windowContainerToken: IBinder
    ): RunningTaskInfo? = runningTasks.firstOrNull { it.token.asBinder() == windowContainerToken }

    fun addRunningTask(task: RunningTaskInfo) {
        runningTasks.add(task)
    }

    fun moveTaskToForeground(task: RunningTaskInfo) {
        _foregroundTask.value = task
    }

    companion object {
        val DEFAULT_TASK = createTask(taskId = -1)
        val LAUNCHER_INTENT: Intent = Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)

        fun createTask(
            taskId: Int,
            token: WindowContainerToken = createToken(),
            baseIntent: Intent = Intent()
        ) =
            RunningTaskInfo().apply {
                this.taskId = taskId
                this.token = token
                this.baseIntent = baseIntent
            }

        fun createToken(): WindowContainerToken {
            val realToken = object : IWindowContainerToken.Stub() {}
            return WindowContainerToken(realToken)
        }
    }
}
+37 −46
Original line number Original line Diff line number Diff line
@@ -16,27 +16,22 @@


package com.android.systemui.mediaprojection.taskswitcher.data.repository
package com.android.systemui.mediaprojection.taskswitcher.data.repository


import android.media.projection.MediaProjectionInfo
import android.media.projection.MediaProjectionManager
import android.os.Binder
import android.os.Binder
import android.os.Handler
import android.os.Handler
import android.os.UserHandle
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
import android.view.ContentRecordingSession
import android.view.ContentRecordingSession
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
import com.android.systemui.util.mockito.any
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.util.mockito.mock
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager.Companion.createToken
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith


@@ -45,29 +40,26 @@ import org.junit.runner.RunWith
@SmallTest
@SmallTest
class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
class MediaProjectionManagerRepositoryTest : SysuiTestCase() {


    private val mediaProjectionManager = mock<MediaProjectionManager>()

    private val dispatcher = StandardTestDispatcher()
    private val dispatcher = StandardTestDispatcher()
    private val testScope = TestScope(dispatcher)
    private val testScope = TestScope(dispatcher)
    private val tasksRepo = FakeTasksRepository()


    private lateinit var callback: MediaProjectionManager.Callback
    private val fakeMediaProjectionManager = FakeMediaProjectionManager()
    private lateinit var repo: MediaProjectionManagerRepository
    private val fakeActivityTaskManager = FakeActivityTaskManager()


    @Before
    private val tasksRepo =
    fun setUp() {
        ActivityTaskManagerTasksRepository(
        whenever(mediaProjectionManager.addCallback(any(), any())).thenAnswer {
            activityTaskManager = fakeActivityTaskManager.activityTaskManager,
            callback = it.arguments[0] as MediaProjectionManager.Callback
            applicationScope = testScope.backgroundScope,
            return@thenAnswer Unit
            backgroundDispatcher = dispatcher
        }
        )
        repo =

    private val repo =
        MediaProjectionManagerRepository(
        MediaProjectionManagerRepository(
                mediaProjectionManager = mediaProjectionManager,
            mediaProjectionManager = fakeMediaProjectionManager.mediaProjectionManager,
            handler = Handler.getMain(),
            handler = Handler.getMain(),
            applicationScope = testScope.backgroundScope,
            applicationScope = testScope.backgroundScope,
            tasksRepository = tasksRepo
            tasksRepository = tasksRepo
        )
        )
    }


    @Test
    @Test
    fun mediaProjectionState_onStart_emitsNotProjecting() =
    fun mediaProjectionState_onStart_emitsNotProjecting() =
@@ -75,7 +67,7 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
            val state by collectLastValue(repo.mediaProjectionState)
            val state by collectLastValue(repo.mediaProjectionState)
            runCurrent()
            runCurrent()


            callback.onStart(TEST_MEDIA_INFO)
            fakeMediaProjectionManager.dispatchOnStart()


            assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
            assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
        }
        }
@@ -86,7 +78,7 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
            val state by collectLastValue(repo.mediaProjectionState)
            val state by collectLastValue(repo.mediaProjectionState)
            runCurrent()
            runCurrent()


            callback.onStop(TEST_MEDIA_INFO)
            fakeMediaProjectionManager.dispatchOnStop()


            assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
            assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
        }
        }
@@ -97,7 +89,7 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
            val state by collectLastValue(repo.mediaProjectionState)
            val state by collectLastValue(repo.mediaProjectionState)
            runCurrent()
            runCurrent()


            callback.onRecordingSessionSet(TEST_MEDIA_INFO, /* session= */ null)
            fakeMediaProjectionManager.dispatchOnSessionSet(session = null)


            assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
            assertThat(state).isEqualTo(MediaProjectionState.NotProjecting)
        }
        }
@@ -108,8 +100,9 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
            val state by collectLastValue(repo.mediaProjectionState)
            val state by collectLastValue(repo.mediaProjectionState)
            runCurrent()
            runCurrent()


            val session = ContentRecordingSession.createDisplaySession(/* displayToMirror= */ 123)
            fakeMediaProjectionManager.dispatchOnSessionSet(
            callback.onRecordingSessionSet(TEST_MEDIA_INFO, session)
                session = ContentRecordingSession.createDisplaySession(/* displayToMirror= */ 123)
            )


            assertThat(state).isEqualTo(MediaProjectionState.EntireScreen)
            assertThat(state).isEqualTo(MediaProjectionState.EntireScreen)
        }
        }
@@ -120,9 +113,10 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
            val state by collectLastValue(repo.mediaProjectionState)
            val state by collectLastValue(repo.mediaProjectionState)
            runCurrent()
            runCurrent()


            val session =
            fakeMediaProjectionManager.dispatchOnSessionSet(
                session =
                    ContentRecordingSession.createTaskSession(/* taskWindowContainerToken= */ null)
                    ContentRecordingSession.createTaskSession(/* taskWindowContainerToken= */ null)
            callback.onRecordingSessionSet(TEST_MEDIA_INFO, session)
            )


            assertThat(state).isEqualTo(MediaProjectionState.EntireScreen)
            assertThat(state).isEqualTo(MediaProjectionState.EntireScreen)
        }
        }
@@ -134,8 +128,9 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
            runCurrent()
            runCurrent()


            val taskWindowContainerToken = Binder()
            val taskWindowContainerToken = Binder()
            val session = ContentRecordingSession.createTaskSession(taskWindowContainerToken)
            fakeMediaProjectionManager.dispatchOnSessionSet(
            callback.onRecordingSessionSet(TEST_MEDIA_INFO, session)
                session = ContentRecordingSession.createTaskSession(taskWindowContainerToken)
            )


            assertThat(state).isEqualTo(MediaProjectionState.EntireScreen)
            assertThat(state).isEqualTo(MediaProjectionState.EntireScreen)
        }
        }
@@ -143,20 +138,16 @@ class MediaProjectionManagerRepositoryTest : SysuiTestCase() {
    @Test
    @Test
    fun mediaProjectionState_sessionSet_taskWithToken_matchingRunningTask_emitsSingleTask() =
    fun mediaProjectionState_sessionSet_taskWithToken_matchingRunningTask_emitsSingleTask() =
        testScope.runTest {
        testScope.runTest {
            val token = FakeTasksRepository.createToken()
            val token = createToken()
            val task = FakeTasksRepository.createTask(taskId = 1, token = token)
            val task = createTask(taskId = 1, token = token)
            tasksRepo.addRunningTask(task)
            fakeActivityTaskManager.addRunningTasks(task)
            val state by collectLastValue(repo.mediaProjectionState)
            val state by collectLastValue(repo.mediaProjectionState)
            runCurrent()
            runCurrent()


            val session = ContentRecordingSession.createTaskSession(token.asBinder())
            fakeMediaProjectionManager.dispatchOnSessionSet(
            callback.onRecordingSessionSet(TEST_MEDIA_INFO, session)
                session = ContentRecordingSession.createTaskSession(token.asBinder())
            )


            assertThat(state).isEqualTo(MediaProjectionState.SingleTask(task))
            assertThat(state).isEqualTo(MediaProjectionState.SingleTask(task))
        }
        }

    companion object {
        val TEST_MEDIA_INFO =
            MediaProjectionInfo(/* packageName= */ "com.test.package", UserHandle.CURRENT)
    }
}
}
+39 −11
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.mediaprojection.taskswitcher.domain.interactor
package com.android.systemui.mediaprojection.taskswitcher.domain.interactor


import android.content.Intent
import android.content.Intent
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
@@ -24,7 +25,9 @@ import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
import com.android.systemui.mediaprojection.taskswitcher.data.repository.ActivityTaskManagerTasksRepository
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager.Companion.createTask
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeMediaProjectionRepository
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeMediaProjectionManager
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeMediaProjectionManager.Companion.createSingleTaskSession
import com.android.systemui.mediaprojection.taskswitcher.data.repository.MediaProjectionManagerRepository
import com.android.systemui.mediaprojection.taskswitcher.domain.model.TaskSwitchState
import com.android.systemui.mediaprojection.taskswitcher.domain.model.TaskSwitchState
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -43,7 +46,8 @@ class TaskSwitchInteractorTest : SysuiTestCase() {
    private val testScope = TestScope(dispatcher)
    private val testScope = TestScope(dispatcher)


    private val fakeActivityTaskManager = FakeActivityTaskManager()
    private val fakeActivityTaskManager = FakeActivityTaskManager()
    private val mediaRepo = FakeMediaProjectionRepository()
    private val fakeMediaProjectionManager = FakeMediaProjectionManager()

    private val tasksRepo =
    private val tasksRepo =
        ActivityTaskManagerTasksRepository(
        ActivityTaskManagerTasksRepository(
            activityTaskManager = fakeActivityTaskManager.activityTaskManager,
            activityTaskManager = fakeActivityTaskManager.activityTaskManager,
@@ -51,15 +55,26 @@ class TaskSwitchInteractorTest : SysuiTestCase() {
            backgroundDispatcher = dispatcher
            backgroundDispatcher = dispatcher
        )
        )


    private val mediaRepo =
        MediaProjectionManagerRepository(
            mediaProjectionManager = fakeMediaProjectionManager.mediaProjectionManager,
            handler = Handler.getMain(),
            applicationScope = testScope.backgroundScope,
            tasksRepository = tasksRepo,
        )

    private val interactor = TaskSwitchInteractor(mediaRepo, tasksRepo)
    private val interactor = TaskSwitchInteractor(mediaRepo, tasksRepo)


    @Test
    @Test
    fun taskSwitchChanges_notProjecting_foregroundTaskChange_emitsNotProjectingTask() =
    fun taskSwitchChanges_notProjecting_foregroundTaskChange_emitsNotProjectingTask() =
        testScope.runTest {
        testScope.runTest {
            mediaRepo.stopProjecting()
            val backgroundTask = createTask(taskId = 0)
            val foregroundTask = createTask(taskId = 1)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)


            fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 1))
            fakeActivityTaskManager.addRunningTasks(backgroundTask, foregroundTask)
            fakeMediaProjectionManager.dispatchOnStop()
            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)


            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.NotProjectingTask)
            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.NotProjectingTask)
        }
        }
@@ -67,10 +82,15 @@ class TaskSwitchInteractorTest : SysuiTestCase() {
    @Test
    @Test
    fun taskSwitchChanges_projectingScreen_foregroundTaskChange_emitsNotProjectingTask() =
    fun taskSwitchChanges_projectingScreen_foregroundTaskChange_emitsNotProjectingTask() =
        testScope.runTest {
        testScope.runTest {
            mediaRepo.projectEntireScreen()
            val backgroundTask = createTask(taskId = 0)
            val foregroundTask = createTask(taskId = 1)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)


            fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 1))
            fakeActivityTaskManager.addRunningTasks(backgroundTask, foregroundTask)
            fakeMediaProjectionManager.dispatchOnSessionSet(
                session = FakeMediaProjectionManager.createDisplaySession()
            )
            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)


            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.NotProjectingTask)
            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.NotProjectingTask)
        }
        }
@@ -80,9 +100,12 @@ class TaskSwitchInteractorTest : SysuiTestCase() {
        testScope.runTest {
        testScope.runTest {
            val projectedTask = createTask(taskId = 0)
            val projectedTask = createTask(taskId = 0)
            val foregroundTask = createTask(taskId = 1)
            val foregroundTask = createTask(taskId = 1)
            mediaRepo.switchProjectedTask(projectedTask)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)


            fakeActivityTaskManager.addRunningTasks(projectedTask, foregroundTask)
            fakeMediaProjectionManager.dispatchOnSessionSet(
                session = createSingleTaskSession(token = projectedTask.token.asBinder())
            )
            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)


            assertThat(taskSwitchState)
            assertThat(taskSwitchState)
@@ -99,9 +122,12 @@ class TaskSwitchInteractorTest : SysuiTestCase() {
        testScope.runTest {
        testScope.runTest {
            val projectedTask = createTask(taskId = 0)
            val projectedTask = createTask(taskId = 0)
            val foregroundTask = createTask(taskId = 1, baseIntent = LAUNCHER_INTENT)
            val foregroundTask = createTask(taskId = 1, baseIntent = LAUNCHER_INTENT)
            mediaRepo.switchProjectedTask(projectedTask)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)


            fakeActivityTaskManager.addRunningTasks(projectedTask, foregroundTask)
            fakeMediaProjectionManager.dispatchOnSessionSet(
                session = createSingleTaskSession(projectedTask.token.asBinder())
            )
            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)


            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.TaskUnchanged)
            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.TaskUnchanged)
@@ -111,11 +137,13 @@ class TaskSwitchInteractorTest : SysuiTestCase() {
    fun taskSwitchChanges_projectingTask_foregroundTaskSame_emitsTaskUnchanged() =
    fun taskSwitchChanges_projectingTask_foregroundTaskSame_emitsTaskUnchanged() =
        testScope.runTest {
        testScope.runTest {
            val projectedTask = createTask(taskId = 0)
            val projectedTask = createTask(taskId = 0)
            val foregroundTask = createTask(taskId = 0)
            mediaRepo.switchProjectedTask(projectedTask)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
            val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)


            fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
            fakeActivityTaskManager.addRunningTasks(projectedTask)
            fakeMediaProjectionManager.dispatchOnSessionSet(
                session = createSingleTaskSession(projectedTask.token.asBinder())
            )
            fakeActivityTaskManager.moveTaskToForeground(projectedTask)


            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.TaskUnchanged)
            assertThat(taskSwitchState).isEqualTo(TaskSwitchState.TaskUnchanged)
        }
        }
Loading