diff --git a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt index be1af64f02..595aa0077b 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt +++ b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt @@ -28,17 +28,9 @@ import com.android.systemui.shared.recents.model.ThumbnailData * and extracted functions from RecentsView to facilitate the implementation of unit tests. */ class RecentsViewUtils { - /** Takes a screenshot of all [taskView] and return map of taskId to the screenshot */ - fun screenshotTasks( - taskView: TaskView, - recentsAnimationController: RecentsAnimationController, - ): Map = - taskView.taskContainers.associate { - it.task.key.id to recentsAnimationController.screenshotTask(it.task.key.id) - } /** - * Sorts task groups to move desktop tasks to the end of the list. + * Sort task groups to move desktop tasks to the end of the list. * * @param tasks List of group tasks to be sorted. * @return Sorted list of GroupTasks to be used in the RecentsView. @@ -48,7 +40,6 @@ class RecentsViewUtils { return otherTasks + desktopTasks } - /** Returns the expected index of the focus task. */ fun getFocusedTaskIndex(taskGroups: List): Int { // The focused task index is placed after the desktop tasks views. return if (enableLargeDesktopWindowingTile()) { @@ -58,8 +49,12 @@ class RecentsViewUtils { } } - /** Counts [TaskView]s that are [DesktopTaskView] instances. */ - fun getDesktopTaskViewCount(taskViews: Iterable): Int = + /** + * Counts [TaskView]s that are [DesktopTaskView] instances. + * + * @param taskViews List of [TaskView]s + */ + fun getDesktopTaskViewCount(taskViews: List): Int = taskViews.count { it is DesktopTaskView } /** Returns a list of all large TaskView Ids from [TaskView]s */ @@ -71,64 +66,18 @@ class RecentsViewUtils { * * @param taskViews List of [TaskView]s */ - fun getFirstLargeTaskView(taskViews: Iterable): TaskView? = + fun getFirstLargeTaskView(taskViews: List): TaskView? = taskViews.firstOrNull { it.isLargeTile } - /** Returns the last TaskView that should be displayed as a large tile. */ - fun getLastLargeTaskView(taskViews: Iterable): TaskView? = - taskViews.lastOrNull { it.isLargeTile } - - /** Returns the first [TaskView], with some tasks possibly hidden in the carousel. */ - fun getFirstTaskViewInCarousel( - nonRunningTaskCategoryHidden: Boolean, - taskViews: Iterable, - runningTaskView: TaskView?, - ): TaskView? = - taskViews.firstOrNull { - it.isVisibleInCarousel(runningTaskView, nonRunningTaskCategoryHidden) - } - - /** Returns the last [TaskView], with some tasks possibly hidden in the carousel. */ - fun getLastTaskViewInCarousel( - nonRunningTaskCategoryHidden: Boolean, - taskViews: Iterable, - runningTaskView: TaskView?, - ): TaskView? = - taskViews.lastOrNull { - it.isVisibleInCarousel(runningTaskView, nonRunningTaskCategoryHidden) + fun screenshotTasks( + taskView: TaskView, + recentsAnimationController: RecentsAnimationController, + ): Map = + taskView.taskContainers.associate { + it.task.key.id to recentsAnimationController.screenshotTask(it.task.key.id) } /** Returns the current list of [TaskView] children. */ - fun getTaskViews(taskViewCount: Int, requireTaskViewAt: (Int) -> TaskView): Iterable = + fun getTaskViews(taskViewCount: Int, requireTaskViewAt: (Int) -> TaskView): List = (0 until taskViewCount).map(requireTaskViewAt) - - /** Apply attachAlpha to all [TaskView] accordingly to different conditions. */ - fun applyAttachAlpha( - taskViews: Iterable, - runningTaskView: TaskView?, - runningTaskTileHidden: Boolean, - nonRunningTaskCategoryHidden: Boolean, - ) { - taskViews.forEach { taskView -> - val isVisible = - if (taskView == runningTaskView) !runningTaskTileHidden - else taskView.isVisibleInCarousel(runningTaskView, nonRunningTaskCategoryHidden) - taskView.attachAlpha = if (isVisible) 1f else 0f - } - } - - private fun TaskView.isVisibleInCarousel( - runningTaskView: TaskView?, - nonRunningTaskCategoryHidden: Boolean, - ): Boolean = - if (!nonRunningTaskCategoryHidden) true - else if (runningTaskView == null) true else getCategory() == runningTaskView.getCategory() - - private fun TaskView.getCategory(): TaskViewCategory = - if (this is DesktopTaskView) TaskViewCategory.DESKTOP else TaskViewCategory.FULL_SCREEN - - private enum class TaskViewCategory { - FULL_SCREEN, - DESKTOP, - } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index bb46a2c3ed..e37e036857 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -681,7 +681,6 @@ public abstract class RecentsView< protected int mRunningTaskViewId = -1; private int mTaskViewIdCount; protected boolean mRunningTaskTileHidden; - private boolean mNonRunningTaskCategoryHidden; @Nullable private Task[] mTmpRunningTasks; protected int mFocusedTaskViewId = INVALID_TASK_ID; @@ -2095,10 +2094,14 @@ public abstract class RecentsView< simulator.fullScreenProgress.value = 0; simulator.recentsViewScale.value = 1; }); - // Reapply runningTask related attributes as they might have been reset by - // resetViewTransforms(). - setRunningTaskViewShowScreenshot(mRunningTaskShowScreenshot); - applyAttachAlpha(); + // Similar to setRunningTaskHidden below, reapply the state before runningTaskView is + // null. + if (!mRunningTaskShowScreenshot) { + setRunningTaskViewShowScreenshot(mRunningTaskShowScreenshot); + } + if (mRunningTaskTileHidden) { + setRunningTaskHidden(mRunningTaskTileHidden); + } updateCurveProperties(); // Update the set of visible task's data @@ -2647,6 +2650,10 @@ public abstract class RecentsView< return getTaskViewFromTaskViewId(mFocusedTaskViewId); } + private @Nullable TaskView getFirstLargeTaskView() { + return mUtils.getFirstLargeTaskView(getTaskViews()); + } + @Nullable private TaskView getTaskViewFromTaskViewId(int taskViewId) { if (taskViewId == -1) { @@ -2742,10 +2749,7 @@ public abstract class RecentsView< showCurrentTask(mActiveGestureRunningTasks); setEnableFreeScroll(false); setEnableDrawingLiveTile(false); - setRunningTaskHidden(true); - if (enableLargeDesktopWindowingTile()) { - setNonRunningTaskCategoryHidden(true); - } + setRunningTaskHidden(!shouldUpdateRunningTaskAlpha()); setTaskIconScaledDown(true); } @@ -2884,9 +2888,6 @@ public abstract class RecentsView< setEnableDrawingLiveTile(mCurrentGestureEndTarget == GestureState.GestureEndTarget.RECENTS); Log.d(TAG, "onGestureAnimationEnd - mEnableDrawingLiveTile: " + mEnableDrawingLiveTile); setRunningTaskHidden(false); - if (enableLargeDesktopWindowingTile()) { - setNonRunningTaskCategoryHidden(false); - } animateUpTaskIconScale(); animateActionsViewIn(); @@ -3042,27 +3043,13 @@ public abstract class RecentsView< if (runningTask == null) { return; } - applyAttachAlpha(); + runningTask.setStableAlpha(isHidden ? 0 : mContentAlpha); if (!isHidden) { AccessibilityManagerCompat.sendCustomAccessibilityEvent( runningTask, AccessibilityEvent.TYPE_VIEW_FOCUSED, null); } } - /** - * Hides the tasks that has a different category (Fullscreen/Desktop) from the running task. - */ - public void setNonRunningTaskCategoryHidden(boolean isHidden) { - mNonRunningTaskCategoryHidden = isHidden; - updateMinAndMaxScrollX(); - applyAttachAlpha(); - } - - private void applyAttachAlpha() { - mUtils.applyAttachAlpha(getTaskViews(), getRunningTaskView(), mRunningTaskTileHidden, - mNonRunningTaskCategoryHidden); - } - private void setRunningTaskViewShowScreenshot(boolean showScreenshot) { setRunningTaskViewShowScreenshot(showScreenshot, /*updatedThumbnails=*/null); } @@ -4460,7 +4447,11 @@ public abstract class RecentsView< alpha = Utilities.boundToRange(alpha, 0, 1); mContentAlpha = alpha; + TaskView runningTaskView = getRunningTaskView(); for (TaskView taskView : getTaskViews()) { + if (runningTaskView != null && mRunningTaskTileHidden && taskView == runningTaskView) { + continue; + } taskView.setStableAlpha(alpha); } mClearAllButton.setContentAlpha(mContentAlpha); @@ -4573,7 +4564,7 @@ public abstract class RecentsView< /** * Returns the current list of [TaskView] children. */ - private Iterable getTaskViews() { + private List getTaskViews() { return mUtils.getTaskViews(getTaskViewCount(), this::requireTaskViewAt); } @@ -5803,42 +5794,26 @@ public abstract class RecentsView< } private int getFirstViewIndex() { - final TaskView firstView; - if (mShowAsGridLastOnLayout) { - // For grid Overivew, it always start if a large tile (focused task or desktop task) if - // they exist, otherwise it start with the first task. - TaskView firstLargeTaskView = mUtils.getFirstLargeTaskView(getTaskViews()); - if (firstLargeTaskView != null) { - firstView = firstLargeTaskView; - } else { - firstView = getTaskViewAt(0); - } - } else { - firstView = mUtils.getFirstTaskViewInCarousel(mNonRunningTaskCategoryHidden, - getTaskViews(), getRunningTaskView()); - } - return indexOfChild(firstView); + TaskView firstTaskView = mShowAsGridLastOnLayout ? getFirstLargeTaskView() : null; + return firstTaskView != null ? indexOfChild(firstTaskView) : 0; } private int getLastViewIndex() { - final View lastView; if (!mDisallowScrollToClearAll) { - // When ClearAllButton is present, it always end with ClearAllButton. - lastView = mClearAllButton; - } else if (mShowAsGridLastOnLayout) { - // When ClearAllButton is absent, for the grid Overview, it always end with a grid task - // if they exist, otherwise it ends with a large tile (focused task or desktop task). - TaskView lastGridTaskView = getLastGridTaskView(); - if (lastGridTaskView != null) { - lastView = lastGridTaskView; - } else { - lastView = mUtils.getLastLargeTaskView(getTaskViews()); - } - } else { - lastView = mUtils.getLastTaskViewInCarousel(mNonRunningTaskCategoryHidden, - getTaskViews(), getRunningTaskView()); + return indexOfChild(mClearAllButton); } - return indexOfChild(lastView); + + if (!mShowAsGridLastOnLayout) { + return getTaskViewCount() - 1; + } + + TaskView lastGridTaskView = getLastGridTaskView(); + if (lastGridTaskView != null) { + return indexOfChild(lastGridTaskView); + } + + // Returns focus task if there are no grid tasks. + return indexOfChild(getFirstLargeTaskView()); } /** diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt index 4dcf2e7cc5..601dae8b27 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.kt +++ b/quickstep/src/com/android/quickstep/views/TaskView.kt @@ -84,6 +84,7 @@ import com.android.quickstep.TaskViewUtils import com.android.quickstep.orientation.RecentsPagedOrientationHandler import com.android.quickstep.recents.di.RecentsDependencies import com.android.quickstep.recents.di.get +import com.android.quickstep.task.thumbnail.TaskThumbnailView import com.android.quickstep.task.viewmodel.TaskViewModel import com.android.quickstep.util.ActiveGestureErrorDetector import com.android.quickstep.util.ActiveGestureLog @@ -200,14 +201,14 @@ constructor( get() = pagedOrientationHandler.getPrimaryValue( SPLIT_SELECT_TRANSLATION_X, - SPLIT_SELECT_TRANSLATION_Y, + SPLIT_SELECT_TRANSLATION_Y ) protected val secondarySplitTranslationProperty: FloatProperty get() = pagedOrientationHandler.getSecondaryValue( SPLIT_SELECT_TRANSLATION_X, - SPLIT_SELECT_TRANSLATION_Y, + SPLIT_SELECT_TRANSLATION_Y ) protected val primaryDismissTranslationProperty: FloatProperty @@ -222,21 +223,21 @@ constructor( get() = pagedOrientationHandler.getPrimaryValue( TASK_OFFSET_TRANSLATION_X, - TASK_OFFSET_TRANSLATION_Y, + TASK_OFFSET_TRANSLATION_Y ) protected val secondaryTaskOffsetTranslationProperty: FloatProperty get() = pagedOrientationHandler.getSecondaryValue( TASK_OFFSET_TRANSLATION_X, - TASK_OFFSET_TRANSLATION_Y, + TASK_OFFSET_TRANSLATION_Y ) protected val taskResistanceTranslationProperty: FloatProperty get() = pagedOrientationHandler.getSecondaryValue( TASK_RESISTANCE_TRANSLATION_X, - TASK_RESISTANCE_TRANSLATION_Y, + TASK_RESISTANCE_TRANSLATION_Y ) private val tempCoordinates = FloatArray(2) @@ -398,7 +399,7 @@ constructor( } get() = taskViewAlpha.get(ALPHA_INDEX_STABLE).value - var attachAlpha + protected var attachAlpha set(value) { taskViewAlpha.get(ALPHA_INDEX_ATTACH).value = value } @@ -434,7 +435,7 @@ constructor( field = value Log.d( TAG, - "${taskIds.contentToString()} - setting border animator visibility to: $field", + "${taskIds.contentToString()} - setting border animator visibility to: $field" ) hoverBorderAnimator?.setBorderVisibility(visible = field, animated = true) } @@ -454,7 +455,7 @@ constructor( FOCUS_TRANSITION, FOCUS_TRANSITION_INDEX_COUNT, { x: Float, y: Float -> x * y }, - 1f, + 1f ) private val focusTransitionFullscreen = focusTransitionPropertyFactory.get(FOCUS_TRANSITION_INDEX_FULLSCREEN) @@ -502,8 +503,8 @@ constructor( this, it.getColor( R.styleable.TaskView_focusBorderColor, - BorderAnimator.DEFAULT_BORDER_COLOR, - ), + BorderAnimator.DEFAULT_BORDER_COLOR + ) ) else null this.hoverBorderAnimator = @@ -518,8 +519,8 @@ constructor( this, it.getColor( R.styleable.TaskView_hoverBorderColor, - BorderAnimator.DEFAULT_BORDER_COLOR, - ), + BorderAnimator.DEFAULT_BORDER_COLOR + ) ) else null } @@ -633,7 +634,7 @@ constructor( addAction( AccessibilityAction( R.id.action_close, - context.getText(R.string.accessibility_close), + context.getText(R.string.accessibility_close) ) ) @@ -657,7 +658,7 @@ constructor( 1, it.taskViewCount - it.indexOfChild(this@TaskView) - 1, 1, - false, + false ) } } @@ -703,7 +704,7 @@ constructor( R.id.show_windows, R.id.digital_wellbeing_toast, STAGE_POSITION_UNDEFINED, - taskOverlayFactory, + taskOverlayFactory ) ) taskContainers.forEach { it.bind() } @@ -741,7 +742,7 @@ constructor( stagePosition, digitalWellBeingToast, findViewById(showWindowViewId)!!, - taskOverlayFactory, + taskOverlayFactory ) } @@ -859,7 +860,7 @@ constructor( if (relativeToDragLayer) { container.dragLayer.getDescendantRectRelativeToSelf( it.snapshotView, - thumbnailBounds, + thumbnailBounds ) } else { thumbnailBounds.set(it.snapshotView) @@ -978,7 +979,7 @@ constructor( @JvmOverloads open fun setShouldShowScreenshot( shouldShowScreenshot: Boolean, - thumbnailDatas: Map? = null, + thumbnailDatas: Map? = null ) { if (this.shouldShowScreenshot == shouldShowScreenshot) return this.shouldShowScreenshot = shouldShowScreenshot @@ -1029,7 +1030,7 @@ constructor( if (!isClickableAsLiveTile) { Log.e( TAG, - "launchAsLiveTile - TaskView is not clickable as a live tile; returning to home: ${taskIds.contentToString()}", + "launchAsLiveTile - TaskView is not clickable as a live tile; returning to home: ${taskIds.contentToString()}" ) return null } @@ -1048,7 +1049,7 @@ constructor( apps.toTypedArray(), wallpapers.toTypedArray(), remoteTargetHandles[0].transformParams.targetSet.nonApps, - remoteTargetHandles[0].transformParams.targetSet.targetMode, + remoteTargetHandles[0].transformParams.targetSet.targetMode ) } if (targets == null) { @@ -1058,7 +1059,7 @@ constructor( if (runnableList == null) { Log.e( TAG, - "launchAsLiveTile - Recents animation cancelled and cannot launch task as non-live tile; returning to home: ${taskIds.contentToString()}", + "launchAsLiveTile - Recents animation cancelled and cannot launch task as non-live tile; returning to home: ${taskIds.contentToString()}" ) } isClickableAsLiveTile = true @@ -1067,7 +1068,7 @@ constructor( TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "composeRecentsLaunchAnimator", - taskIds.contentToString(), + taskIds.contentToString() ) val runnableList = RunnableList() with(AnimatorSet()) { @@ -1080,7 +1081,7 @@ constructor( true /* launcherClosing */, recentsView.stateManager, recentsView, - recentsView.depthController, + recentsView.depthController ) addListener( object : AnimatorListenerAdapter() { @@ -1117,7 +1118,7 @@ constructor( TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", - taskIds.contentToString(), + taskIds.contentToString() ) val opts = container.getActivityLaunchOptions(this, null).apply { @@ -1129,7 +1130,7 @@ constructor( ) { Log.d( TAG, - "launchAsStaticTile - startActivityFromRecents: ${taskIds.contentToString()}", + "launchAsStaticTile - startActivityFromRecents: ${taskIds.contentToString()}" ) ActiveGestureLog.INSTANCE.trackEvent( ActiveGestureErrorDetector.GestureEvent.EXPECTING_TASK_APPEARED @@ -1162,12 +1163,12 @@ constructor( @JvmOverloads open fun launchWithoutAnimation( isQuickSwitch: Boolean = false, - callback: (launched: Boolean) -> Unit, + callback: (launched: Boolean) -> Unit ) { TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", - taskIds.contentToString(), + taskIds.contentToString() ) val firstContainer = taskContainers[0] val failureListener = TaskRemovedDuringLaunchListener(context.applicationContext) @@ -1198,7 +1199,7 @@ constructor( 0, 0, Executors.MAIN_EXECUTOR.handler, - { callback(true) }, + { callback(true) } ) { failureListener.onTransitionFinished() } @@ -1226,7 +1227,7 @@ constructor( } Log.d( TAG, - "launchWithoutAnimation - startActivityFromRecents: ${taskIds.contentToString()}", + "launchWithoutAnimation - startActivityFromRecents: ${taskIds.contentToString()}" ) } } @@ -1245,7 +1246,7 @@ constructor( recentsView?.initiateSplitSelect( this, splitPositionOption.stagePosition, - SplitConfigurationOptions.getLogEventForPosition(splitPositionOption.stagePosition), + SplitConfigurationOptions.getLogEventForPosition(splitPositionOption.stagePosition) ) } @@ -1268,7 +1269,7 @@ constructor( container.splitAnimationThumbnail, /* intent */ null, /* user */ null, - container.itemInfo, + container.itemInfo ) } @@ -1373,13 +1374,13 @@ constructor( this[0] = viewHalfWidth this[1] = viewHalfHeight }, - false, + false ) transformingTouchDelegate.setBounds( (tempCenterCoordinates[0] - viewHalfWidth).toInt(), (tempCenterCoordinates[1] - viewHalfHeight).toInt(), (tempCenterCoordinates[0] + viewHalfWidth).toInt(), - (tempCenterCoordinates[1] + viewHalfHeight).toInt(), + (tempCenterCoordinates[1] + viewHalfHeight).toInt() ) } @@ -1389,7 +1390,7 @@ constructor( it.showWindowsView?.let { showWindowsView -> updateFilterCallback( showWindowsView, - getFilterUpdateCallback(it.task.key.packageName), + getFilterUpdateCallback(it.task.key.packageName) ) } } @@ -1592,7 +1593,10 @@ constructor( resetViewTransforms() } - fun resetViewTransforms() { + fun getTaskContainerForTaskThumbnailView(taskThumbnailView: TaskThumbnailView): TaskContainer? = + taskContainers.firstOrNull { it.thumbnailView == taskThumbnailView } + + open fun resetViewTransforms() { // fullscreenTranslation and accumulatedTranslation should not be reset, as // resetViewTransforms is called during QuickSwitch scrolling. dismissTranslationX = 0f @@ -1706,7 +1710,7 @@ constructor( Interpolators.clampToProgress( Interpolators.FAST_OUT_SLOW_IN, 1f - FOCUS_TRANSITION_THRESHOLD, - 1f, + 1f )!! private val SYSTEM_GESTURE_EXCLUSION_RECT = listOf(Rect())