Partial Screen Sharing: Task Switcher - Domain Layer implementation
Implements the domain layer: - Defines model/state - Implements the interactor that is responsible for knowing whether a task switch has happened, in the context of task projection - Implements fake repositories to be used in unit tests Bug: 286201261 Test: TaskSwitchInteractorTest.kt Change-Id: I46ff1214c97a52e63893bc728c2fa191b08b7c6e
This commit is contained in:
committed by
Chris Göllner
parent
92f65330d2
commit
6f22f3af64
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.domain.interactor
|
||||
|
||||
import android.app.TaskInfo
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.mediaprojection.taskswitcher.data.model.MediaProjectionState
|
||||
import com.android.systemui.mediaprojection.taskswitcher.data.repository.MediaProjectionRepository
|
||||
import com.android.systemui.mediaprojection.taskswitcher.data.repository.TasksRepository
|
||||
import com.android.systemui.mediaprojection.taskswitcher.domain.model.TaskSwitchState
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
/** Interactor with logic related to task switching in the context of media projection. */
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SysUISingleton
|
||||
class TaskSwitchInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
mediaProjectionRepository: MediaProjectionRepository,
|
||||
private val tasksRepository: TasksRepository,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Emits a stream of changes to the state of task switching, in the context of media projection.
|
||||
*/
|
||||
val taskSwitchChanges: Flow<TaskSwitchState> =
|
||||
mediaProjectionRepository.mediaProjectionState.flatMapLatest { projectionState ->
|
||||
Log.d(TAG, "MediaProjectionState -> $projectionState")
|
||||
when (projectionState) {
|
||||
is MediaProjectionState.SingleTask -> {
|
||||
val projectedTask = projectionState.task
|
||||
tasksRepository.foregroundTask.map { foregroundTask ->
|
||||
if (hasForegroundTaskSwitched(projectedTask, foregroundTask)) {
|
||||
TaskSwitchState.TaskSwitched(projectedTask, foregroundTask)
|
||||
} else {
|
||||
TaskSwitchState.TaskUnchanged
|
||||
}
|
||||
}
|
||||
}
|
||||
is MediaProjectionState.EntireScreen,
|
||||
is MediaProjectionState.NotProjecting -> {
|
||||
flowOf(TaskSwitchState.NotProjectingTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether tasks have been switched.
|
||||
*
|
||||
* Always returns `false` when launcher is in the foreground. The reason is that when going to
|
||||
* recents to switch apps, launcher becomes the new foreground task, and we don't want to show
|
||||
* the notification then.
|
||||
*/
|
||||
private fun hasForegroundTaskSwitched(projectedTask: TaskInfo, foregroundTask: TaskInfo) =
|
||||
projectedTask.taskId != foregroundTask.taskId && !foregroundTask.isLauncher
|
||||
|
||||
private val TaskInfo.isLauncher
|
||||
get() =
|
||||
baseIntent.hasCategory(Intent.CATEGORY_HOME) && baseIntent.action == Intent.ACTION_MAIN
|
||||
|
||||
companion object {
|
||||
private const val TAG = "TaskSwitchInteractor"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.domain.model
|
||||
|
||||
import android.app.TaskInfo
|
||||
|
||||
/** Represents tha state of task switching in the context of single task media projection. */
|
||||
sealed interface TaskSwitchState {
|
||||
/** Currently no task is being projected. */
|
||||
object NotProjectingTask : TaskSwitchState
|
||||
/** The foreground task is the same as the task that is currently being projected. */
|
||||
object TaskUnchanged : TaskSwitchState
|
||||
/** The foreground task is a different one to the task it currently being projected. */
|
||||
data class TaskSwitched(val projectedTask: TaskInfo, val foregroundTask: TaskInfo) :
|
||||
TaskSwitchState
|
||||
}
|
||||
@@ -16,67 +16,41 @@
|
||||
|
||||
package com.android.systemui.mediaprojection.taskswitcher.data.repository
|
||||
|
||||
import android.app.ActivityManager.RunningTaskInfo
|
||||
import android.app.ActivityTaskManager
|
||||
import android.app.TaskStackListener
|
||||
import android.os.Binder
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.window.IWindowContainerToken
|
||||
import android.window.WindowContainerToken
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager.Companion.createTask
|
||||
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeActivityTaskManager.Companion.createToken
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class ActivityTaskManagerTasksRepositoryTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var activityTaskManager: ActivityTaskManager
|
||||
private val fakeActivityTaskManager = FakeActivityTaskManager()
|
||||
|
||||
private val dispatcher = StandardTestDispatcher()
|
||||
private val dispatcher = UnconfinedTestDispatcher()
|
||||
private val testScope = TestScope(dispatcher)
|
||||
|
||||
private lateinit var repo: ActivityTaskManagerTasksRepository
|
||||
private lateinit var taskStackListener: TaskStackListener
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
whenever(activityTaskManager.registerTaskStackListener(any())).thenAnswer {
|
||||
taskStackListener = it.arguments[0] as TaskStackListener
|
||||
return@thenAnswer Unit
|
||||
}
|
||||
repo =
|
||||
ActivityTaskManagerTasksRepository(
|
||||
activityTaskManager,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
backgroundDispatcher = dispatcher
|
||||
)
|
||||
}
|
||||
private val repo =
|
||||
ActivityTaskManagerTasksRepository(
|
||||
activityTaskManager = fakeActivityTaskManager.activityTaskManager,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
backgroundDispatcher = dispatcher
|
||||
)
|
||||
|
||||
@Test
|
||||
fun findRunningTaskFromWindowContainerToken_noMatch_returnsNull() {
|
||||
whenever(activityTaskManager.getTasks(Integer.MAX_VALUE))
|
||||
.thenReturn(
|
||||
listOf(
|
||||
createTaskInfo(newTaskId = 1, windowContainerToken = createToken()),
|
||||
createTaskInfo(newTaskId = 2, windowContainerToken = createToken())
|
||||
)
|
||||
)
|
||||
fakeActivityTaskManager.addRunningTasks(createTask(taskId = 1), createTask(taskId = 2))
|
||||
|
||||
testScope.runTest {
|
||||
val matchingTask =
|
||||
@@ -89,15 +63,12 @@ class ActivityTaskManagerTasksRepositoryTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun findRunningTaskFromWindowContainerToken_matchingToken_returnsTaskInfo() {
|
||||
val expectedToken = createToken()
|
||||
val expectedTask = createTaskInfo(newTaskId = 1, windowContainerToken = expectedToken)
|
||||
val expectedTask = createTask(taskId = 1, token = expectedToken)
|
||||
|
||||
whenever(activityTaskManager.getTasks(Integer.MAX_VALUE))
|
||||
.thenReturn(
|
||||
listOf(
|
||||
createTaskInfo(newTaskId = 2, windowContainerToken = createToken()),
|
||||
expectedTask
|
||||
)
|
||||
)
|
||||
fakeActivityTaskManager.addRunningTasks(
|
||||
createTask(taskId = 2),
|
||||
expectedTask,
|
||||
)
|
||||
|
||||
testScope.runTest {
|
||||
val actualTask =
|
||||
@@ -113,15 +84,14 @@ class ActivityTaskManagerTasksRepositoryTest : SysuiTestCase() {
|
||||
fun foregroundTask_returnsStreamOfTasksMovedToFront() =
|
||||
testScope.runTest {
|
||||
val foregroundTask by collectLastValue(repo.foregroundTask)
|
||||
runCurrent()
|
||||
|
||||
taskStackListener.onTaskMovedToFront(createTaskInfo(newTaskId = 1))
|
||||
fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 1))
|
||||
assertThat(foregroundTask?.taskId).isEqualTo(1)
|
||||
|
||||
taskStackListener.onTaskMovedToFront(createTaskInfo(newTaskId = 2))
|
||||
fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 2))
|
||||
assertThat(foregroundTask?.taskId).isEqualTo(2)
|
||||
|
||||
taskStackListener.onTaskMovedToFront(createTaskInfo(newTaskId = 3))
|
||||
fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 3))
|
||||
assertThat(foregroundTask?.taskId).isEqualTo(3)
|
||||
}
|
||||
|
||||
@@ -129,26 +99,10 @@ class ActivityTaskManagerTasksRepositoryTest : SysuiTestCase() {
|
||||
fun foregroundTask_lastValueIsCached() =
|
||||
testScope.runTest {
|
||||
val foregroundTaskA by collectLastValue(repo.foregroundTask)
|
||||
runCurrent()
|
||||
taskStackListener.onTaskMovedToFront(createTaskInfo(newTaskId = 1))
|
||||
fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 1))
|
||||
assertThat(foregroundTaskA?.taskId).isEqualTo(1)
|
||||
|
||||
val foregroundTaskB by collectLastValue(repo.foregroundTask)
|
||||
assertThat(foregroundTaskB?.taskId).isEqualTo(1)
|
||||
}
|
||||
|
||||
private fun createToken(): WindowContainerToken {
|
||||
val realToken = object : IWindowContainerToken.Stub() {}
|
||||
return WindowContainerToken(realToken)
|
||||
}
|
||||
|
||||
private fun createTaskInfo(
|
||||
windowContainerToken: WindowContainerToken = createToken(),
|
||||
newTaskId: Int,
|
||||
): RunningTaskInfo {
|
||||
return RunningTaskInfo().apply {
|
||||
token = windowContainerToken
|
||||
taskId = newTaskId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.app.ActivityTaskManager
|
||||
import android.app.TaskStackListener
|
||||
import android.content.Intent
|
||||
import android.window.IWindowContainerToken
|
||||
import android.window.WindowContainerToken
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
|
||||
class FakeActivityTaskManager {
|
||||
|
||||
private val runningTasks = mutableListOf<RunningTaskInfo>()
|
||||
private val taskTaskListeners = mutableListOf<TaskStackListener>()
|
||||
|
||||
val activityTaskManager = mock<ActivityTaskManager>()
|
||||
|
||||
init {
|
||||
whenever(activityTaskManager.registerTaskStackListener(any())).thenAnswer {
|
||||
taskTaskListeners += it.arguments[0] as TaskStackListener
|
||||
return@thenAnswer Unit
|
||||
}
|
||||
whenever(activityTaskManager.unregisterTaskStackListener(any())).thenAnswer {
|
||||
taskTaskListeners -= it.arguments[0] as TaskStackListener
|
||||
return@thenAnswer Unit
|
||||
}
|
||||
whenever(activityTaskManager.getTasks(any())).thenAnswer {
|
||||
val maxNumTasks = it.arguments[0] as Int
|
||||
return@thenAnswer runningTasks.take(maxNumTasks)
|
||||
}
|
||||
}
|
||||
|
||||
fun moveTaskToForeground(task: RunningTaskInfo) {
|
||||
taskTaskListeners.forEach { it.onTaskMovedToFront(task) }
|
||||
}
|
||||
|
||||
fun addRunningTasks(vararg tasks: RunningTaskInfo) {
|
||||
runningTasks += tasks
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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,0 +1,127 @@
|
||||
/*
|
||||
* 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.domain.interactor
|
||||
|
||||
import android.content.Intent
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
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.Companion.createTask
|
||||
import com.android.systemui.mediaprojection.taskswitcher.data.repository.FakeMediaProjectionRepository
|
||||
import com.android.systemui.mediaprojection.taskswitcher.domain.model.TaskSwitchState
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class TaskSwitchInteractorTest : SysuiTestCase() {
|
||||
|
||||
private val dispatcher = UnconfinedTestDispatcher()
|
||||
private val testScope = TestScope(dispatcher)
|
||||
|
||||
private val fakeActivityTaskManager = FakeActivityTaskManager()
|
||||
private val mediaRepo = FakeMediaProjectionRepository()
|
||||
private val tasksRepo =
|
||||
ActivityTaskManagerTasksRepository(
|
||||
activityTaskManager = fakeActivityTaskManager.activityTaskManager,
|
||||
applicationScope = testScope.backgroundScope,
|
||||
backgroundDispatcher = dispatcher
|
||||
)
|
||||
|
||||
private val interactor = TaskSwitchInteractor(mediaRepo, tasksRepo)
|
||||
|
||||
@Test
|
||||
fun taskSwitchChanges_notProjecting_foregroundTaskChange_emitsNotProjectingTask() =
|
||||
testScope.runTest {
|
||||
mediaRepo.stopProjecting()
|
||||
val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
|
||||
|
||||
fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 1))
|
||||
|
||||
assertThat(taskSwitchState).isEqualTo(TaskSwitchState.NotProjectingTask)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskSwitchChanges_projectingScreen_foregroundTaskChange_emitsNotProjectingTask() =
|
||||
testScope.runTest {
|
||||
mediaRepo.projectEntireScreen()
|
||||
val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
|
||||
|
||||
fakeActivityTaskManager.moveTaskToForeground(createTask(taskId = 1))
|
||||
|
||||
assertThat(taskSwitchState).isEqualTo(TaskSwitchState.NotProjectingTask)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskSwitchChanges_projectingTask_foregroundTaskDifferent_emitsTaskChanged() =
|
||||
testScope.runTest {
|
||||
val projectedTask = createTask(taskId = 0)
|
||||
val foregroundTask = createTask(taskId = 1)
|
||||
mediaRepo.switchProjectedTask(projectedTask)
|
||||
val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
|
||||
|
||||
fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
|
||||
|
||||
assertThat(taskSwitchState)
|
||||
.isEqualTo(
|
||||
TaskSwitchState.TaskSwitched(
|
||||
projectedTask = projectedTask,
|
||||
foregroundTask = foregroundTask
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskSwitchChanges_projectingTask_foregroundTaskLauncher_emitsTaskUnchanged() =
|
||||
testScope.runTest {
|
||||
val projectedTask = createTask(taskId = 0)
|
||||
val foregroundTask = createTask(taskId = 1, baseIntent = LAUNCHER_INTENT)
|
||||
mediaRepo.switchProjectedTask(projectedTask)
|
||||
val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
|
||||
|
||||
fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
|
||||
|
||||
assertThat(taskSwitchState).isEqualTo(TaskSwitchState.TaskUnchanged)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskSwitchChanges_projectingTask_foregroundTaskSame_emitsTaskUnchanged() =
|
||||
testScope.runTest {
|
||||
val projectedTask = createTask(taskId = 0)
|
||||
val foregroundTask = createTask(taskId = 0)
|
||||
mediaRepo.switchProjectedTask(projectedTask)
|
||||
val taskSwitchState by collectLastValue(interactor.taskSwitchChanges)
|
||||
|
||||
fakeActivityTaskManager.moveTaskToForeground(foregroundTask)
|
||||
|
||||
assertThat(taskSwitchState).isEqualTo(TaskSwitchState.TaskUnchanged)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LAUNCHER_INTENT: Intent =
|
||||
Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user