Change actions view disabling logic
1. Introduces "central task" - the task relating to the actions view 2. Decouple the overlay and actions view 3. Undo filter of taskViewType == SINGLE for overlay as it can be enabled for split tasks as well Bug: 402351284 Flag: com.android.launcher3.enable_refactor_task_thumbnail Test: OverviewImageTest (attached abtd run) Test: OverviewMenuImageTest (attached abtd run) Change-Id: Id7bc5c9c6620183d91e99d9dc5d2980eb8e3ec36
This commit is contained in:
@@ -37,6 +37,7 @@ data class TaskTileUiState(
|
||||
val hasHeader: Boolean,
|
||||
val sysUiStatusNavFlags: Int,
|
||||
val taskOverlayEnabled: Boolean,
|
||||
val isCentralTask: Boolean,
|
||||
)
|
||||
|
||||
sealed class TaskData {
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.android.quickstep.recents.domain.usecase.IsThumbnailValidUseCase
|
||||
import com.android.quickstep.recents.domain.usecase.ThumbnailPosition
|
||||
import com.android.quickstep.recents.viewmodel.RecentsViewData
|
||||
import com.android.quickstep.views.TaskViewType
|
||||
import com.android.quickstep.views.TaskViewType.SINGLE
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -66,6 +65,12 @@ class TaskViewModel(
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
|
||||
private val isCentralTask =
|
||||
combine(taskIds, recentsViewData.centralTaskIds) { taskIds, centralTaskIds ->
|
||||
taskIds == centralTaskIds
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
|
||||
private val taskData =
|
||||
taskIds.flatMapLatest { ids ->
|
||||
// Combine Tasks requests
|
||||
@@ -79,14 +84,12 @@ class TaskViewModel(
|
||||
combine(recentsViewData.overlayEnabled, recentsViewData.settledFullyVisibleTaskIds) {
|
||||
isOverlayEnabled,
|
||||
settledFullyVisibleTaskIds ->
|
||||
taskViewType == SINGLE &&
|
||||
isOverlayEnabled &&
|
||||
settledFullyVisibleTaskIds.any { it in taskIds.value }
|
||||
isOverlayEnabled && settledFullyVisibleTaskIds.any { it in taskIds.value }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
|
||||
val state: Flow<TaskTileUiState> =
|
||||
combine(taskData, isLiveTile, overlayEnabled, ::mapToTaskTile)
|
||||
combine(taskData, isLiveTile, overlayEnabled, isCentralTask, ::mapToTaskTile)
|
||||
.distinctUntilChanged()
|
||||
.flowOn(dispatcherProvider.background)
|
||||
|
||||
@@ -114,6 +117,7 @@ class TaskViewModel(
|
||||
tasks: List<TaskData>,
|
||||
isLiveTile: Boolean,
|
||||
overlayEnabled: Boolean,
|
||||
isCentralTask: Boolean,
|
||||
): TaskTileUiState {
|
||||
val firstThumbnailData = (tasks.firstOrNull() as? TaskData.Data)?.thumbnailData
|
||||
return TaskTileUiState(
|
||||
@@ -122,6 +126,7 @@ class TaskViewModel(
|
||||
hasHeader = taskViewType == TaskViewType.DESKTOP,
|
||||
sysUiStatusNavFlags = getSysUiStatusNavFlagsUseCase(firstThumbnailData),
|
||||
taskOverlayEnabled = overlayEnabled,
|
||||
isCentralTask = isCentralTask,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ class RecentsViewData {
|
||||
// The settled set of visible taskIds that is updated after RecentsView scroll settles.
|
||||
val settledFullyVisibleTaskIds = MutableStateFlow(emptySet<Int>())
|
||||
|
||||
// The id for the task ids in the TaskView that controls the Actions View
|
||||
val centralTaskIds = MutableStateFlow(emptySet<Int>())
|
||||
|
||||
// A list of taskIds that are associated with a RecentsAnimationController. */
|
||||
val runningTaskIds = MutableStateFlow(emptySet<Int>())
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ class RecentsViewModel(
|
||||
recentsViewData.settledFullyVisibleTaskIds.value = taskIds
|
||||
}
|
||||
|
||||
fun updateCentralTaskIds(taskIds: Set<Int>) {
|
||||
recentsViewData.centralTaskIds.value = taskIds
|
||||
}
|
||||
|
||||
fun setOverlayEnabled(isOverlayEnabled: Boolean) {
|
||||
recentsViewData.overlayEnabled.value = isOverlayEnabled
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ public abstract class RecentsView<
|
||||
*/
|
||||
private boolean mAnyTaskHasBeenDismissed;
|
||||
|
||||
private final RecentsViewModel mRecentsViewModel;
|
||||
protected final RecentsViewModel mRecentsViewModel;
|
||||
private final RecentsViewModelHelper mHelper;
|
||||
protected final RecentsViewUtils mUtils = new RecentsViewUtils(this);
|
||||
protected final RecentsDismissUtils mDismissUtils = new RecentsDismissUtils(this);
|
||||
@@ -1595,7 +1595,7 @@ public abstract class RecentsView<
|
||||
/**
|
||||
* Returns true if the given TaskView is in expected scroll position.
|
||||
*/
|
||||
public boolean isTaskInExpectedScrollPosition(TaskView taskView) {
|
||||
public boolean isTaskInExpectedScrollPosition(@NonNull TaskView taskView) {
|
||||
return getScrollForPage(indexOfChild(taskView))
|
||||
== getPagedOrientationHandler().getPrimaryScroll(this);
|
||||
}
|
||||
@@ -5993,6 +5993,9 @@ public abstract class RecentsView<
|
||||
updateCurrentTaskActionsVisibility();
|
||||
loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
|
||||
updateEnabledOverlays();
|
||||
if (enableRefactorTaskThumbnail()) {
|
||||
mUtils.updateCentralTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -391,6 +391,27 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) {
|
||||
}
|
||||
}
|
||||
|
||||
fun updateCentralTask() {
|
||||
val isTablet: Boolean = getDeviceProfile().isTablet
|
||||
val actionsViewCanRelateToTaskView = !(isTablet && enableGridOnlyOverview())
|
||||
val focusedTaskView = recentsView.focusedTaskView
|
||||
val currentPageTaskView = recentsView.currentPageTaskView
|
||||
|
||||
fun isInExpectedScrollPosition(taskView: TaskView?) =
|
||||
taskView?.let { recentsView.isTaskInExpectedScrollPosition(it) } ?: false
|
||||
|
||||
val centralTaskIds: Set<Int> =
|
||||
when {
|
||||
!actionsViewCanRelateToTaskView -> emptySet()
|
||||
isTablet && isInExpectedScrollPosition(focusedTaskView) ->
|
||||
focusedTaskView!!.taskIdSet
|
||||
isInExpectedScrollPosition(currentPageTaskView) -> currentPageTaskView!!.taskIdSet
|
||||
else -> emptySet()
|
||||
}
|
||||
|
||||
recentsView.mRecentsViewModel.updateCentralTaskIds(centralTaskIds)
|
||||
}
|
||||
|
||||
var deskExplodeProgress: Float = 0f
|
||||
set(value) {
|
||||
field = value
|
||||
|
||||
@@ -100,6 +100,8 @@ import com.android.quickstep.util.TaskRemovedDuringLaunchListener
|
||||
import com.android.quickstep.util.displayId
|
||||
import com.android.quickstep.util.isExternalDisplay
|
||||
import com.android.quickstep.views.IconAppChipView.AppChipStatus
|
||||
import com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBNAIL
|
||||
import com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED
|
||||
import com.android.quickstep.views.RecentsView.UNBOUND_TASK_VIEW_ID
|
||||
import com.android.systemui.shared.recents.model.Task
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData
|
||||
@@ -829,6 +831,20 @@ constructor(
|
||||
height = container.thumbnailView.height,
|
||||
)
|
||||
container.setOverlayEnabled(state.taskOverlayEnabled, thumbnailPosition)
|
||||
if (state.isCentralTask) {
|
||||
this.container.actionsView.let {
|
||||
it.updateDisabledFlags(
|
||||
DISABLED_ROTATED,
|
||||
thumbnailPosition?.isRotated ?: false,
|
||||
)
|
||||
it.updateDisabledFlags(
|
||||
DISABLED_NO_THUMBNAIL,
|
||||
state.tasks.any { taskData ->
|
||||
(taskData as? TaskData.Data)?.thumbnailData?.thumbnail == null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (enableOverviewIconMenu()) {
|
||||
setIconState(container, containerState)
|
||||
|
||||
+25
-22
@@ -85,6 +85,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_LIGHT_THEME,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -132,6 +133,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_LIGHT_THEME,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -155,6 +157,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_LIGHT_THEME,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -178,6 +181,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_LIGHT_THEME,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -200,6 +204,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_LIGHT_THEME,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -218,6 +223,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_LIGHT_THEME,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -233,6 +239,7 @@ class TaskViewModelTest {
|
||||
hasHeader = false,
|
||||
sysUiStatusNavFlags = FLAGS_APPEARANCE_DEFAULT,
|
||||
taskOverlayEnabled = false,
|
||||
isCentralTask = false,
|
||||
)
|
||||
assertThat(sut.state.first()).isEqualTo(expectedResult)
|
||||
}
|
||||
@@ -247,28 +254,6 @@ class TaskViewModelTest {
|
||||
assertThat(sut.state.first().taskOverlayEnabled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskOverlayDisabled_when_usingGroupedTask() =
|
||||
testScope.runTest {
|
||||
sut = createTaskViewModel(TaskViewType.GROUPED)
|
||||
sut.bind(TASK_MODEL_1.id)
|
||||
recentsViewData.overlayEnabled.value = true
|
||||
recentsViewData.settledFullyVisibleTaskIds.value = setOf(1)
|
||||
|
||||
assertThat(sut.state.first().taskOverlayEnabled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskOverlayDisabled_when_usingDesktopTask() =
|
||||
testScope.runTest {
|
||||
sut = createTaskViewModel(TaskViewType.DESKTOP)
|
||||
sut.bind(TASK_MODEL_1.id)
|
||||
recentsViewData.overlayEnabled.value = true
|
||||
recentsViewData.settledFullyVisibleTaskIds.value = setOf(1)
|
||||
|
||||
assertThat(sut.state.first().taskOverlayEnabled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun taskOverlayDisabled_when_OverlayIsEnabledForInvisibleTask() =
|
||||
testScope.runTest {
|
||||
@@ -289,6 +274,24 @@ class TaskViewModelTest {
|
||||
assertThat(sut.state.first().taskOverlayEnabled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isCentralTask_when_CentralTaskIdsMatchTaskIds() =
|
||||
testScope.runTest {
|
||||
sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id)
|
||||
recentsViewData.centralTaskIds.value = setOf(TASK_MODEL_1.id, TASK_MODEL_2.id)
|
||||
|
||||
assertThat(sut.state.first().isCentralTask).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isNotCentralTask_when_CentralTaskIdsDoMatchTaskIds() =
|
||||
testScope.runTest {
|
||||
sut.bind(TASK_MODEL_1.id, TASK_MODEL_2.id)
|
||||
recentsViewData.centralTaskIds.value = setOf(TASK_MODEL_3.id)
|
||||
|
||||
assertThat(sut.state.first().isCentralTask).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldShowSplash_calls_useCase() {
|
||||
sut.isThumbnailValid(null, 0, 0)
|
||||
|
||||
Reference in New Issue
Block a user