mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-03-01 00:06:47 +00:00
Merge "Refactor TaskView.getTaskIds and its attribute container to support any number of tasks" into main
This commit is contained in:
@@ -53,6 +53,7 @@ import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsState>
|
||||
implements StateListener<RecentsState> {
|
||||
@@ -144,8 +145,9 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
@Override
|
||||
public void setCurrentTask(int runningTaskViewId) {
|
||||
super.setCurrentTask(runningTaskViewId);
|
||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
||||
if (mHomeTask != null && mHomeTask.key.id != runningTaskId) {
|
||||
int[] runningTaskIds = getTaskIdsForRunningTaskView();
|
||||
if (mHomeTask != null
|
||||
&& Arrays.stream(runningTaskIds).noneMatch(taskId -> taskId == mHomeTask.key.id)) {
|
||||
mHomeTask = null;
|
||||
setRunningTaskHidden(false);
|
||||
}
|
||||
@@ -182,13 +184,14 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
|
||||
// track the index of the next task appropriately, as if we are switching on any other app.
|
||||
// TODO(b/195607777) Confirm home task info is front-most task and not mixed in with others
|
||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
||||
if (mHomeTask != null && mHomeTask.key.id == runningTaskId
|
||||
int[] runningTaskIds = getTaskIdsForRunningTaskView();
|
||||
if (mHomeTask != null
|
||||
&& Arrays.stream(runningTaskIds).allMatch(taskId -> taskId == mHomeTask.key.id)
|
||||
&& !taskGroups.isEmpty()) {
|
||||
// Check if the task list has running task
|
||||
boolean found = false;
|
||||
for (GroupTask group : taskGroups) {
|
||||
if (group.containsTask(runningTaskId)) {
|
||||
if (Arrays.stream(runningTaskIds).allMatch(group::containsTask)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -204,18 +204,14 @@ public class DesktopTaskView extends TaskView {
|
||||
}
|
||||
|
||||
private void updateTaskIdContainer() {
|
||||
// TODO(b/249371338): TaskView expects the array to have at least 2 elements.
|
||||
// At least 2 elements in the array
|
||||
mTaskIdContainer = new int[Math.max(mTasks.size(), 2)];
|
||||
mTaskIdContainer = new int[mTasks.size()];
|
||||
for (int i = 0; i < mTasks.size(); i++) {
|
||||
mTaskIdContainer[i] = mTasks.get(i).key.id;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTaskIdAttributeContainer() {
|
||||
// TODO(b/249371338): TaskView expects the array to have at least 2 elements.
|
||||
// At least 2 elements in the array
|
||||
mTaskIdAttributeContainer = new TaskIdAttributeContainer[Math.max(mTasks.size(), 2)];
|
||||
mTaskIdAttributeContainer = new TaskIdAttributeContainer[mTasks.size()];
|
||||
for (int i = 0; i < mTasks.size(); i++) {
|
||||
Task task = mTasks.get(i);
|
||||
TaskThumbnailViewDeprecated thumbnailView = mSnapshotViewMap.get(task.key.id);
|
||||
@@ -247,12 +243,6 @@ public class DesktopTaskView extends TaskView {
|
||||
return mTaskThumbnailViewDeprecated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsTaskId(int taskId) {
|
||||
// Thumbnail map contains taskId -> thumbnail map. Use the keys for contains
|
||||
return mSnapshotViewMap.contains(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTaskListVisibilityChanged(boolean visible, int changes) {
|
||||
cancelPendingLoadTasks();
|
||||
|
||||
@@ -6,6 +6,7 @@ import static com.android.launcher3.Flags.enableOverviewIconMenu;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.quickstep.util.SplitScreenUtils.convertLauncherSplitBoundsToShell;
|
||||
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
@@ -46,6 +47,7 @@ import kotlin.Unit;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -129,9 +131,11 @@ public class GroupedTaskView extends TaskView {
|
||||
@Nullable SplitBounds splitBoundsConfig) {
|
||||
super.bind(primary, orientedState);
|
||||
mSecondaryTask = secondary;
|
||||
mTaskIdContainer[1] = secondary.key.id;
|
||||
mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2,
|
||||
mIconView2, STAGE_POSITION_BOTTOM_OR_RIGHT);
|
||||
mTaskIdContainer = new int[]{mTaskIdContainer[0], secondary.key.id};
|
||||
mTaskIdAttributeContainer = new TaskIdAttributeContainer[]{
|
||||
mTaskIdAttributeContainer[0],
|
||||
new TaskIdAttributeContainer(secondary, mSnapshotView2,
|
||||
mIconView2, STAGE_POSITION_BOTTOM_OR_RIGHT)};
|
||||
mTaskIdAttributeContainer[0].setStagePosition(
|
||||
SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT);
|
||||
mSnapshotView2.bind(secondary);
|
||||
@@ -154,6 +158,9 @@ public class GroupedTaskView extends TaskView {
|
||||
public void setUpShowAllInstancesListener() {
|
||||
// sets up the listener for the left/top task
|
||||
super.setUpShowAllInstancesListener();
|
||||
if (mTaskIdAttributeContainer.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// right/bottom task's base package name
|
||||
String taskPackageName = mTaskIdAttributeContainer[1].getTask().key.getPackageName();
|
||||
@@ -307,17 +314,21 @@ public class GroupedTaskView extends TaskView {
|
||||
mSnapshotView2.refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsTaskId(int taskId) {
|
||||
return (mTask != null && mTask.key.id == taskId)
|
||||
|| (mSecondaryTask != null && mSecondaryTask.key.id == taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskThumbnailViewDeprecated[] getThumbnails() {
|
||||
return new TaskThumbnailViewDeprecated[]{mTaskThumbnailViewDeprecated, mSnapshotView2};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns taskId that split selection was initiated with,
|
||||
* {@link ActivityTaskManager#INVALID_TASK_ID} if no tasks in this TaskView are part of
|
||||
* split selection
|
||||
*/
|
||||
protected int getThisTaskCurrentlyInSplitSelection() {
|
||||
int initialTaskId = getRecentsView().getSplitSelectController().getInitialTaskId();
|
||||
return containsTaskId(initialTaskId) ? initialTaskId : INVALID_TASK_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLastSelectedChildTaskIndex() {
|
||||
SplitSelectStateController splitSelectController =
|
||||
@@ -382,13 +393,15 @@ public class GroupedTaskView extends TaskView {
|
||||
} else {
|
||||
// Currently being split with this taskView, let the non-split selected thumbnail
|
||||
// take up full thumbnail area
|
||||
TaskIdAttributeContainer container =
|
||||
mTaskIdAttributeContainer[initSplitTaskId == mTask.key.id ? 1 : 0];
|
||||
container.getThumbnailView().measure(widthMeasureSpec,
|
||||
View.MeasureSpec.makeMeasureSpec(
|
||||
heightSize -
|
||||
mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx,
|
||||
MeasureSpec.EXACTLY));
|
||||
Optional<TaskIdAttributeContainer> nonSplitContainer = Arrays.stream(
|
||||
mTaskIdAttributeContainer).filter(
|
||||
container -> container.getTask().key.id != initSplitTaskId).findAny();
|
||||
nonSplitContainer.ifPresent(
|
||||
taskIdAttributeContainer -> taskIdAttributeContainer.getThumbnailView().measure(
|
||||
widthMeasureSpec, MeasureSpec.makeMeasureSpec(
|
||||
heightSize - mContainer.getDeviceProfile()
|
||||
.overviewTaskThumbnailTopMarginPx,
|
||||
MeasureSpec.EXACTLY)));
|
||||
}
|
||||
if (!enableOverviewIconMenu()) {
|
||||
updateIconPlacement();
|
||||
@@ -529,7 +542,7 @@ public class GroupedTaskView extends TaskView {
|
||||
mDigitalWellBeingToast.setBannerVisibility(visibility);
|
||||
mSnapshotView2.setVisibility(visibility);
|
||||
mDigitalWellBeingToast2.setBannerVisibility(visibility);
|
||||
} else if (taskId == getTaskIds()[0]) {
|
||||
} else if (mTaskIdContainer.length > 0 && mTaskIdContainer[0] == taskId) {
|
||||
mTaskThumbnailViewDeprecated.setVisibility(visibility);
|
||||
mDigitalWellBeingToast.setBannerVisibility(visibility);
|
||||
} else {
|
||||
|
||||
@@ -626,7 +626,6 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
*/
|
||||
protected int mRunningTaskViewId = -1;
|
||||
private int mTaskViewIdCount;
|
||||
private final int[] INVALID_TASK_IDS = new int[]{-1, -1};
|
||||
protected boolean mRunningTaskTileHidden;
|
||||
@Nullable
|
||||
private Task[] mTmpRunningTasks;
|
||||
@@ -1413,7 +1412,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
*/
|
||||
@Nullable
|
||||
public TaskView getTaskViewByTaskIds(int[] taskIds) {
|
||||
if (!hasAnyValidTaskIds(taskIds)) {
|
||||
if (!hasAllValidTaskIds(taskIds)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1432,9 +1431,11 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Returns false if {@code taskIds} is null or contains invalid values, true otherwise */
|
||||
private boolean hasAnyValidTaskIds(int[] taskIds) {
|
||||
return taskIds != null && !Arrays.equals(taskIds, INVALID_TASK_IDS);
|
||||
/** Returns false if {@code taskIds} is null or contains any invalid values, true otherwise */
|
||||
private boolean hasAllValidTaskIds(int[] taskIds) {
|
||||
return taskIds != null
|
||||
&& taskIds.length > 0
|
||||
&& Arrays.stream(taskIds).noneMatch(taskId -> taskId == INVALID_TASK_ID);
|
||||
}
|
||||
|
||||
public void setOverviewStateEnabled(boolean enabled) {
|
||||
@@ -1720,10 +1721,12 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
return;
|
||||
}
|
||||
|
||||
int[] currentTaskId = INVALID_TASK_IDS;
|
||||
int[] currentTaskIds;
|
||||
TaskView currentTaskView = getTaskViewAt(mCurrentPage);
|
||||
if (currentTaskView != null && currentTaskView.getTask() != null) {
|
||||
currentTaskId = currentTaskView.getTaskIds();
|
||||
currentTaskIds = currentTaskView.getTaskIds();
|
||||
} else {
|
||||
currentTaskIds = new int[0];
|
||||
}
|
||||
|
||||
// Unload existing visible task data
|
||||
@@ -1735,8 +1738,8 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
|
||||
// Save running task ID if it exists before rebinding all taskViews, otherwise the task from
|
||||
// the runningTaskView currently bound could get assigned to another TaskView
|
||||
int[] runningTaskId = getTaskIdsForTaskViewId(mRunningTaskViewId);
|
||||
int[] focusedTaskId = getTaskIdsForTaskViewId(mFocusedTaskViewId);
|
||||
int[] runningTaskIds = getTaskIdsForTaskViewId(mRunningTaskViewId);
|
||||
int[] focusedTaskIds = getTaskIdsForTaskViewId(mFocusedTaskViewId);
|
||||
|
||||
// Reset the focused task to avoiding initializing TaskViews layout as focused task during
|
||||
// binding. The focused task view will be updated after all the TaskViews are bound.
|
||||
@@ -1819,7 +1822,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
}
|
||||
|
||||
// Keep same previous focused task
|
||||
TaskView newFocusedTaskView = getTaskViewByTaskIds(focusedTaskId);
|
||||
TaskView newFocusedTaskView = getTaskViewByTaskIds(focusedTaskIds);
|
||||
// If the list changed, maybe the focused task doesn't exist anymore
|
||||
if (newFocusedTaskView == null && getTaskViewCount() > 0) {
|
||||
newFocusedTaskView = getTaskViewAt(0);
|
||||
@@ -1830,10 +1833,10 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
updateChildTaskOrientations();
|
||||
|
||||
TaskView newRunningTaskView = null;
|
||||
if (hasAnyValidTaskIds(runningTaskId)) {
|
||||
if (hasAllValidTaskIds(runningTaskIds)) {
|
||||
// Update mRunningTaskViewId to be the new TaskView that was assigned by binding
|
||||
// the full list of tasks to taskViews
|
||||
newRunningTaskView = getTaskViewByTaskIds(runningTaskId);
|
||||
newRunningTaskView = getTaskViewByTaskIds(runningTaskIds);
|
||||
if (newRunningTaskView != null) {
|
||||
setRunningTaskViewId(newRunningTaskView.getTaskViewId());
|
||||
} else {
|
||||
@@ -1853,8 +1856,8 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
if (mNextPage != INVALID_PAGE) {
|
||||
// Restore mCurrentPage but don't call setCurrentPage() as that clobbers the scroll.
|
||||
mCurrentPage = previousCurrentPage;
|
||||
if (hasAnyValidTaskIds(currentTaskId)) {
|
||||
currentTaskView = getTaskViewByTaskIds(currentTaskId);
|
||||
if (hasAllValidTaskIds(currentTaskIds)) {
|
||||
currentTaskView = getTaskViewByTaskIds(currentTaskIds);
|
||||
if (currentTaskView != null) {
|
||||
targetPage = indexOfChild(currentTaskView);
|
||||
}
|
||||
@@ -1863,7 +1866,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
targetPage = previousFocusedPage;
|
||||
} else {
|
||||
// Set the current page to the running task, but not if settling on new task.
|
||||
if (hasAnyValidTaskIds(runningTaskId)) {
|
||||
if (hasAllValidTaskIds(runningTaskIds)) {
|
||||
targetPage = indexOfChild(newRunningTaskView);
|
||||
} else if (getTaskViewCount() > 0) {
|
||||
targetPage = indexOfChild(requireTaskViewAt(0));
|
||||
@@ -1963,7 +1966,8 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
public void resetTaskVisuals() {
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (mIgnoreResetTaskId != taskView.getTaskIds()[0]) {
|
||||
if (Arrays.stream(taskView.getTaskIds()).noneMatch(
|
||||
taskId -> taskId == mIgnoreResetTaskId)) {
|
||||
taskView.resetViewTransforms();
|
||||
taskView.setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
|
||||
taskView.setStableAlpha(mContentAlpha);
|
||||
@@ -2343,7 +2347,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
TaskIdAttributeContainer[] containers = taskView.getTaskIdAttributeContainers();
|
||||
if (containers[0] == null && containers[1] == null) {
|
||||
if (containers.length == 0) {
|
||||
continue;
|
||||
}
|
||||
int index = indexOfChild(taskView);
|
||||
@@ -2498,7 +2502,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
// For now 2 distinct task IDs is max for split screen
|
||||
TaskView runningTaskView = getTaskViewFromTaskViewId(taskViewId);
|
||||
if (runningTaskView == null) {
|
||||
return INVALID_TASK_IDS;
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
return runningTaskView.getTaskIds();
|
||||
@@ -2736,22 +2740,19 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
* Returns true if we should add a stub taskView for the running task id
|
||||
*/
|
||||
protected boolean shouldAddStubTaskView(Task[] runningTasks) {
|
||||
TaskView taskView = getTaskViewByTaskId(runningTasks[0].key.id);
|
||||
if (taskView == null) {
|
||||
// No TaskView found, add a stub task.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (runningTasks.length > 1) {
|
||||
// Ensure all taskIds matches the TaskView, otherwise add a stub task.
|
||||
return Arrays.stream(runningTasks).anyMatch(
|
||||
runningTask -> !taskView.containsTaskId(runningTask.key.id));
|
||||
int[] runningTaskIds = Arrays.stream(runningTasks).mapToInt(task -> task.key.id).toArray();
|
||||
TaskView matchingTaskView = null;
|
||||
if (hasDesktopTask(runningTasks) && runningTaskIds.length == 1) {
|
||||
// TODO(b/249371338): Unsure if it's expected, desktop runningTasks only have a single
|
||||
// taskId, therefore we match any DesktopTaskView that contains the runningTaskId.
|
||||
TaskView taskview = getTaskViewByTaskId(runningTaskIds[0]);
|
||||
if (taskview instanceof DesktopTaskView) {
|
||||
matchingTaskView = taskview;
|
||||
}
|
||||
} else {
|
||||
// Ensure the TaskView only contains a single taskId, or is a DesktopTask,
|
||||
// otherwise add a stub task.
|
||||
// TODO(b/249371338): Figure out why DesktopTask only have a single runningTask.
|
||||
return taskView.containsMultipleTasks() && !taskView.isDesktopTask();
|
||||
matchingTaskView = getTaskViewByTaskIds(runningTaskIds);
|
||||
}
|
||||
return matchingTaskView == null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4273,13 +4274,10 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
alpha = Utilities.boundToRange(alpha, 0, 1);
|
||||
mContentAlpha = alpha;
|
||||
|
||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
||||
TaskView runningTaskView = getRunningTaskView();
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
TaskView child = requireTaskViewAt(i);
|
||||
int[] childTaskIds = child.getTaskIds();
|
||||
if (runningTaskId != INVALID_TASK_ID
|
||||
&& mRunningTaskTileHidden
|
||||
&& (childTaskIds[0] == runningTaskId || childTaskIds[1] == runningTaskId)) {
|
||||
if (runningTaskView != null && mRunningTaskTileHidden && child == runningTaskView) {
|
||||
continue;
|
||||
}
|
||||
child.setStableAlpha(alpha);
|
||||
@@ -4753,7 +4751,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
|
||||
// Prevent dismissing whole task if we're only initiating from one of 2 tasks in split pair
|
||||
mSplitSelectStateController.setDismissingFromSplitPair(mSplitHiddenTaskView != null
|
||||
&& mSplitHiddenTaskView.containsMultipleTasks());
|
||||
&& mSplitHiddenTaskView instanceof GroupedTaskView);
|
||||
mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent,
|
||||
splitSelectSource.position.stagePosition, splitSelectSource.itemInfo,
|
||||
splitSelectSource.splitEvent, splitSelectSource.alreadyRunningTaskId);
|
||||
@@ -4774,14 +4772,14 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
mSplitSelectStateController.isAnimateCurrentTaskDismissal();
|
||||
boolean isInitiatingTaskViewSplitPair =
|
||||
mSplitSelectStateController.isDismissingFromSplitPair();
|
||||
if (isInitiatingSplitFromTaskView && isInitiatingTaskViewSplitPair) {
|
||||
if (isInitiatingSplitFromTaskView && isInitiatingTaskViewSplitPair
|
||||
&& mSplitHiddenTaskView instanceof GroupedTaskView) {
|
||||
// Splitting from Overview for split pair task
|
||||
createInitialSplitSelectAnimation(builder);
|
||||
|
||||
// Animate pair thumbnail into full thumbnail
|
||||
boolean primaryTaskSelected =
|
||||
mSplitHiddenTaskView.getTaskIdAttributeContainers()[0].getTask().key.id ==
|
||||
mSplitSelectStateController.getInitialTaskId();
|
||||
boolean primaryTaskSelected = mSplitHiddenTaskView.getTaskIds()[0]
|
||||
== mSplitSelectStateController.getInitialTaskId();
|
||||
TaskIdAttributeContainer taskIdAttributeContainer = mSplitHiddenTaskView
|
||||
.getTaskIdAttributeContainers()[primaryTaskSelected ? 1 : 0];
|
||||
TaskThumbnailViewDeprecated thumbnail = taskIdAttributeContainer.getThumbnailView();
|
||||
@@ -5232,7 +5230,8 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
|
||||
mPendingAnimation.addEndListener(isSuccess -> {
|
||||
if (isSuccess) {
|
||||
if (tv.getTaskIds()[1] != -1 && mRemoteTargetHandles != null) {
|
||||
if (tv instanceof GroupedTaskView && hasAllValidTaskIds(tv.getTaskIds())
|
||||
&& mRemoteTargetHandles != null) {
|
||||
// TODO(b/194414938): make this part of the animations instead.
|
||||
TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
|
||||
mRemoteTargetHandles[0].getTransformParams().getTargetSet().nonApps,
|
||||
@@ -5879,8 +5878,7 @@ public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewCo
|
||||
}
|
||||
|
||||
taskView.setShowScreenshot(true);
|
||||
for (TaskIdAttributeContainer container :
|
||||
taskView.getTaskIdAttributeContainers()) {
|
||||
for (TaskIdAttributeContainer container : taskView.getTaskIdAttributeContainers()) {
|
||||
if (container == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.quickstep.views;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
@@ -48,7 +47,6 @@ import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.IdRes;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -127,6 +125,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -150,7 +149,8 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
*/
|
||||
@Retention(SOURCE)
|
||||
@IntDef({FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL, FLAG_UPDATE_CORNER_RADIUS})
|
||||
public @interface TaskDataChanges {}
|
||||
public @interface TaskDataChanges {
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of task view
|
||||
@@ -371,12 +371,9 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
private float mStableAlpha = 1;
|
||||
|
||||
private int mTaskViewId = -1;
|
||||
/**
|
||||
* Index 0 will contain taskID of left/top task, index 1 will contain taskId of bottom/right
|
||||
*/
|
||||
protected int[] mTaskIdContainer = new int[]{-1, -1};
|
||||
protected int[] mTaskIdContainer = new int[0];
|
||||
protected TaskIdAttributeContainer[] mTaskIdAttributeContainer =
|
||||
new TaskIdAttributeContainer[2];
|
||||
new TaskIdAttributeContainer[0];
|
||||
|
||||
private boolean mShowScreenshot;
|
||||
private boolean mBorderEnabled;
|
||||
@@ -395,9 +392,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
private boolean mIsClickableAsLiveTile = true;
|
||||
|
||||
@Nullable private final BorderAnimator mFocusBorderAnimator;
|
||||
@Nullable
|
||||
private final BorderAnimator mFocusBorderAnimator;
|
||||
|
||||
@Nullable private final BorderAnimator mHoverBorderAnimator;
|
||||
@Nullable
|
||||
private final BorderAnimator mHoverBorderAnimator;
|
||||
|
||||
public TaskView(Context context) {
|
||||
this(context, null);
|
||||
@@ -674,10 +673,10 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
public void bind(Task task, RecentsOrientedState orientedState) {
|
||||
cancelPendingLoadTasks();
|
||||
mTask = task;
|
||||
mTaskIdContainer[0] = mTask.key.id;
|
||||
mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task,
|
||||
mTaskThumbnailViewDeprecated, mIconView,
|
||||
STAGE_POSITION_UNDEFINED);
|
||||
mTaskIdContainer = new int[]{mTask.key.id};
|
||||
mTaskIdAttributeContainer = new TaskIdAttributeContainer[]{
|
||||
new TaskIdAttributeContainer(task, mTaskThumbnailViewDeprecated, mIconView,
|
||||
STAGE_POSITION_UNDEFINED)};
|
||||
if (enableRefactorTaskThumbnail()) {
|
||||
bindTaskThumbnailView();
|
||||
} else {
|
||||
@@ -696,6 +695,9 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
* Sets up an on-click listener and the visibility for show_windows icon on top of the task.
|
||||
*/
|
||||
public void setUpShowAllInstancesListener() {
|
||||
if (mTaskIdAttributeContainer.length == 0) {
|
||||
return;
|
||||
}
|
||||
String taskPackageName = mTaskIdAttributeContainer[0].mTask.key.getPackageName();
|
||||
|
||||
// icon of the top/left task
|
||||
@@ -751,19 +753,18 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
* Check if given {@code taskId} is tracked in this view
|
||||
*/
|
||||
public boolean containsTaskId(int taskId) {
|
||||
return mTask != null && mTask.key.id == taskId;
|
||||
return Arrays.stream(mTaskIdContainer).anyMatch(myTaskId -> myTaskId == taskId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer array of two elements to be size consistent with max number of tasks possible
|
||||
* index 0 will contain the taskId, index 1 will be -1 indicating a null taskID value
|
||||
* Returns a copy of integer array containing taskIds of all tasks in the TaskView.
|
||||
*/
|
||||
public int[] getTaskIds() {
|
||||
return Arrays.copyOf(mTaskIdContainer, mTaskIdContainer.length);
|
||||
}
|
||||
|
||||
public boolean containsMultipleTasks() {
|
||||
return mTaskIdContainer[1] != -1;
|
||||
return mTaskIdContainer.length > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -833,25 +834,6 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return taskId that split selection was initiated with,
|
||||
* {@link ActivityTaskManager#INVALID_TASK_ID} if no tasks in this TaskView are part of
|
||||
* split selection
|
||||
*/
|
||||
protected int getThisTaskCurrentlyInSplitSelection() {
|
||||
SplitSelectStateController splitSelectController =
|
||||
getRecentsView().getSplitSelectController();
|
||||
int initSplitTaskId = INVALID_TASK_ID;
|
||||
for (TaskIdAttributeContainer container : getTaskIdAttributeContainers()) {
|
||||
int taskId = container.getTask().key.id;
|
||||
if (taskId == splitSelectController.getInitialTaskId()) {
|
||||
initSplitTaskId = taskId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return initSplitTaskId;
|
||||
}
|
||||
|
||||
private void onClick(View view) {
|
||||
if (getTask() == null) {
|
||||
Log.d("b/310064698", "onClick - task is null");
|
||||
@@ -872,10 +854,13 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
/**
|
||||
* @return {@code true} if user is already in split select mode and this tap was to choose the
|
||||
* second app. {@code false} otherwise
|
||||
* second app. {@code false} otherwise
|
||||
*/
|
||||
protected boolean confirmSecondSplitSelectApp() {
|
||||
int index = getLastSelectedChildTaskIndex();
|
||||
if (index >= mTaskIdAttributeContainer.length) {
|
||||
return false;
|
||||
}
|
||||
TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
|
||||
if (container != null) {
|
||||
return getRecentsView().confirmSplitSelect(this, container.getTask(),
|
||||
@@ -897,6 +882,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
/**
|
||||
* Starts the task associated with this view and animates the startup.
|
||||
*
|
||||
* @return CompletionStage to indicate the animation completion or null if the launch failed.
|
||||
*/
|
||||
@Nullable
|
||||
@@ -904,7 +890,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
if (mTask != null) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
|
||||
ActivityOptionsWrapper opts = mContainer.getActivityLaunchOptions(this, null);
|
||||
ActivityOptionsWrapper opts = mContainer.getActivityLaunchOptions(this, null);
|
||||
opts.options.setLaunchDisplayId(
|
||||
getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
|
||||
if (ActivityManagerWrapper.getInstance()
|
||||
@@ -1092,6 +1078,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
/**
|
||||
* See {@link TaskDataChanges}
|
||||
*
|
||||
* @param visible If this task view will be visible to the user in overview or hidden
|
||||
*/
|
||||
public void onTaskListVisibilityChanged(boolean visible) {
|
||||
@@ -1100,6 +1087,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
/**
|
||||
* See {@link TaskDataChanges}
|
||||
*
|
||||
* @param visible If this task view will be visible to the user in overview or hidden
|
||||
*/
|
||||
public void onTaskListVisibilityChanged(boolean visible, @TaskDataChanges int changes) {
|
||||
@@ -1188,29 +1176,34 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
}
|
||||
|
||||
protected boolean showTaskMenuWithContainer(TaskViewIcon iconView) {
|
||||
TaskIdAttributeContainer menuContainer =
|
||||
mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
|
||||
Optional<TaskIdAttributeContainer> menuContainer = Arrays.stream(
|
||||
mTaskIdAttributeContainer).filter(
|
||||
container -> container.getIconView() == iconView).findAny();
|
||||
if (menuContainer.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
DeviceProfile dp = mContainer.getDeviceProfile();
|
||||
if (enableOverviewIconMenu() && iconView instanceof IconAppChipView) {
|
||||
((IconAppChipView) iconView).revealAnim(/* isRevealing= */ true);
|
||||
return TaskMenuView.showForTask(menuContainer,
|
||||
return TaskMenuView.showForTask(menuContainer.get(),
|
||||
() -> ((IconAppChipView) iconView).revealAnim(/* isRevealing= */ false));
|
||||
} else if (dp.isTablet) {
|
||||
int alignedOptionIndex = 0;
|
||||
if (getRecentsView().isOnGridBottomRow(menuContainer.getTaskView()) && dp.isLandscape) {
|
||||
if (getRecentsView().isOnGridBottomRow(menuContainer.get().getTaskView())
|
||||
&& dp.isLandscape) {
|
||||
if (Flags.enableGridOnlyOverview()) {
|
||||
// With no focused task, there is less available space below the tasks, so align
|
||||
// the arrow to the third option in the menu.
|
||||
alignedOptionIndex = 2;
|
||||
} else {
|
||||
} else {
|
||||
// Bottom row of landscape grid aligns arrow to second option to avoid clipping
|
||||
alignedOptionIndex = 1;
|
||||
}
|
||||
}
|
||||
return TaskMenuViewWithArrow.Companion.showForTask(menuContainer,
|
||||
return TaskMenuViewWithArrow.Companion.showForTask(menuContainer.get(),
|
||||
alignedOptionIndex);
|
||||
} else {
|
||||
return TaskMenuView.showForTask(menuContainer);
|
||||
return TaskMenuView.showForTask(menuContainer.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1664,9 +1657,6 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
final Context context = getContext();
|
||||
for (TaskIdAttributeContainer taskContainer : mTaskIdAttributeContainer) {
|
||||
if (taskContainer == null) {
|
||||
continue;
|
||||
}
|
||||
for (SystemShortcut s : TraceHelper.allowIpcs(
|
||||
"TV.a11yInfo", () -> getEnabledShortcuts(this, taskContainer))) {
|
||||
info.addAction(s.createAccessibilityAction(context));
|
||||
@@ -1702,9 +1692,6 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
}
|
||||
|
||||
for (TaskIdAttributeContainer taskContainer : mTaskIdAttributeContainer) {
|
||||
if (taskContainer == null) {
|
||||
continue;
|
||||
}
|
||||
for (SystemShortcut s : getEnabledShortcuts(this,
|
||||
taskContainer)) {
|
||||
if (s.hasHandlerForAction(action)) {
|
||||
@@ -1903,13 +1890,13 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
|
||||
private int getRootViewDisplayId() {
|
||||
Display display = getRootView().getDisplay();
|
||||
Display display = getRootView().getDisplay();
|
||||
return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visibility for the thumbnail and associated elements (DWB banners and action chips).
|
||||
* IconView is unaffected.
|
||||
* Sets visibility for the thumbnail and associated elements (DWB banners and action chips).
|
||||
* IconView is unaffected.
|
||||
*
|
||||
* @param taskId is only used when setting visibility to a non-{@link View#VISIBLE} value
|
||||
*/
|
||||
@@ -1966,7 +1953,8 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() { }
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
|
||||
public class TaskIdAttributeContainer {
|
||||
|
||||
Reference in New Issue
Block a user