1 /* <lambda>null2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.mediaprojection.taskswitcher.ui.viewmodel 18 19 import android.app.ActivityManager.RunningTaskInfo 20 import android.util.Log 21 import androidx.annotation.VisibleForTesting 22 import com.android.systemui.dagger.qualifiers.Background 23 import com.android.systemui.mediaprojection.taskswitcher.domain.interactor.TaskSwitchInteractor 24 import com.android.systemui.mediaprojection.taskswitcher.domain.model.TaskSwitchState 25 import com.android.systemui.mediaprojection.taskswitcher.ui.model.TaskSwitcherNotificationUiState 26 import javax.inject.Inject 27 import kotlin.time.Duration.Companion.seconds 28 import kotlinx.coroutines.CoroutineDispatcher 29 import kotlinx.coroutines.delay 30 import kotlinx.coroutines.flow.Flow 31 import kotlinx.coroutines.flow.map 32 import kotlinx.coroutines.flow.transformLatest 33 import kotlinx.coroutines.withContext 34 35 class TaskSwitcherNotificationViewModel 36 @Inject 37 constructor( 38 private val interactor: TaskSwitchInteractor, 39 @Background private val backgroundDispatcher: CoroutineDispatcher, 40 ) { 41 42 val uiState: Flow<TaskSwitcherNotificationUiState> = 43 interactor.taskSwitchChanges 44 .map { taskSwitchChange -> 45 Log.d(TAG, "taskSwitchChange: $taskSwitchChange") 46 when (taskSwitchChange) { 47 is TaskSwitchState.TaskSwitched -> { 48 TaskSwitcherNotificationUiState.Showing( 49 projectedTask = taskSwitchChange.projectedTask, 50 foregroundTask = taskSwitchChange.foregroundTask, 51 ) 52 } 53 is TaskSwitchState.NotProjectingTask, 54 is TaskSwitchState.TaskUnchanged -> { 55 TaskSwitcherNotificationUiState.NotShowing 56 } 57 } 58 } 59 .transformLatest { uiState -> 60 emit(uiState) 61 if (uiState is TaskSwitcherNotificationUiState.Showing) { 62 delay(NOTIFICATION_MAX_SHOW_DURATION) 63 Log.d(TAG, "Auto hiding notification after $NOTIFICATION_MAX_SHOW_DURATION") 64 emit(TaskSwitcherNotificationUiState.NotShowing) 65 } 66 } 67 68 suspend fun onSwitchTaskClicked(task: RunningTaskInfo) { 69 interactor.switchProjectedTask(task) 70 } 71 72 suspend fun onGoBackToTaskClicked(task: RunningTaskInfo) = 73 withContext(backgroundDispatcher) { interactor.goBackToTask(task) } 74 75 companion object { 76 @VisibleForTesting val NOTIFICATION_MAX_SHOW_DURATION = 5.seconds 77 private const val TAG = "TaskSwitchNotifVM" 78 } 79 } 80