From 7caf5f0ea42d2da30b183c220c1a3a6a1bd93115 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 20 Sep 2021 15:39:13 -0700 Subject: [PATCH] Show distinct TaskMenus for each task in GroupedTaskView * For now we only show the App Info option for each task icon clicked for GroupedTaskView * Have TaskMenuView operate on a specific task instead of only a TaskView * NOTE: getItemInfo() in TaskIdAttributeContainer needs to dynamically call getItemInfo(Task) because at the time of creation of the container in TaskView#bind(), the task object provided initially is a palceholder task which only has a taskId and no other attributes set. getItemInfo() needs a non-null baseIntent, which the placeholder task doesn't have. Right fix for this is to have GestureState hold onto multiple running tasks when in split screen that are provided by ActivityManagerWrapper when the gesture starts (but that change is extensive and out of scope w/ this workaround available) Bug: 181704764 Test: Open TaskMenuView's w/ either task icon for GroupedTaskView, opens up corresponding tasks menu. Change-Id: I70b7c13394ad4980cabbd611cb928bb03d8a2924 --- .../android/quickstep/TaskOverlayFactory.java | 16 ++-- .../quickstep/TaskShortcutFactory.java | 77 ++++++++++++------- .../quickstep/views/GroupedTaskView.java | 16 +++- .../android/quickstep/views/TaskMenuView.java | 72 +++++++++++------ .../com/android/quickstep/views/TaskView.java | 72 +++++++++++------ 5 files changed, 172 insertions(+), 81 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java index 978fb570ca..e3e7b33848 100644 --- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java @@ -51,6 +51,7 @@ import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskThumbnailView; import com.android.quickstep.views.TaskView; +import com.android.quickstep.views.TaskView.TaskIdAttributeContainer; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -63,11 +64,16 @@ import java.util.List; public class TaskOverlayFactory implements ResourceBasedOverride { public static List getEnabledShortcuts(TaskView taskView, - DeviceProfile deviceProfile) { + DeviceProfile deviceProfile, TaskIdAttributeContainer taskContainer) { final ArrayList shortcuts = new ArrayList<>(); final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext()); + boolean hasMultipleTasks = taskView.getTaskIds()[1] != -1; for (TaskShortcutFactory menuOption : MENU_OPTIONS) { - SystemShortcut shortcut = menuOption.getShortcut(activity, taskView); + if (hasMultipleTasks && !menuOption.showForSplitscreen()) { + continue; + } + + SystemShortcut shortcut = menuOption.getShortcut(activity, taskContainer); if (shortcut == null) { continue; } @@ -87,7 +93,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { if (!canLauncherRotate && isInLandscape) { // Add screenshot action to task menu. SystemShortcut screenshotShortcut = TaskShortcutFactory.SCREENSHOT - .getShortcut(activity, taskView); + .getShortcut(activity, taskContainer); if (screenshotShortcut != null) { shortcuts.add(screenshotShortcut); } @@ -95,7 +101,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { // Add modal action only if display orientation is the same as the device orientation. if (orientedState.getDisplayRotation() == ROTATION_0) { SystemShortcut modalShortcut = TaskShortcutFactory.MODAL - .getShortcut(activity, taskView); + .getShortcut(activity, taskContainer); if (modalShortcut != null) { shortcuts.add(modalShortcut); } @@ -105,7 +111,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { } - public static void addSplitOptions(List outShortcuts, + private static void addSplitOptions(List outShortcuts, BaseDraggingActivity activity, TaskView taskView, DeviceProfile deviceProfile) { int[] taskViewTaskIds = taskView.getTaskIds(); boolean alreadyHasMultipleTasks = taskViewTaskIds[0] != -1 && diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index 559125ea97..dbb5f10d18 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -45,6 +45,7 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskThumbnailView; import com.android.quickstep.views.TaskView; +import com.android.quickstep.views.TaskView.TaskIdAttributeContainer; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat; import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture; @@ -61,9 +62,25 @@ import java.util.List; * Represents a system shortcut that can be shown for a recent task. */ public interface TaskShortcutFactory { - SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView view); + SystemShortcut getShortcut(BaseDraggingActivity activity, + TaskIdAttributeContainer taskContainer); - TaskShortcutFactory APP_INFO = (activity, view) -> new AppInfo(activity, view.getItemInfo()); + default boolean showForSplitscreen() { + return false; + } + + TaskShortcutFactory APP_INFO = new TaskShortcutFactory() { + @Override + public SystemShortcut getShortcut(BaseDraggingActivity activity, + TaskIdAttributeContainer taskContainer) { + return new AppInfo(activity, taskContainer.getItemInfo()); + } + + @Override + public boolean showForSplitscreen() { + return true; + } + }; abstract class MultiWindowFactory implements TaskShortcutFactory { @@ -82,15 +99,16 @@ public interface TaskShortcutFactory { protected abstract boolean onActivityStarted(BaseDraggingActivity activity); @Override - public SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView taskView) { - final Task task = taskView.getTask(); + public SystemShortcut getShortcut(BaseDraggingActivity activity, + TaskIdAttributeContainer taskContainer) { + final Task task = taskContainer.getTask(); if (!task.isDockable) { return null; } if (!isAvailable(activity, task.key.displayId)) { return null; } - return new MultiWindowSystemShortcut(mIconRes, mTextRes, activity, taskView, this, + return new MultiWindowSystemShortcut(mIconRes, mTextRes, activity, taskContainer, this, mLauncherEvent); } } @@ -123,13 +141,14 @@ public interface TaskShortcutFactory { private final LauncherEvent mLauncherEvent; public MultiWindowSystemShortcut(int iconRes, int textRes, BaseDraggingActivity activity, - TaskView taskView, MultiWindowFactory factory, LauncherEvent launcherEvent) { - super(iconRes, textRes, activity, taskView.getItemInfo()); + TaskIdAttributeContainer taskContainer, MultiWindowFactory factory, + LauncherEvent launcherEvent) { + super(iconRes, textRes, activity, taskContainer.getItemInfo()); mLauncherEvent = launcherEvent; mHandler = new Handler(Looper.getMainLooper()); - mTaskView = taskView; + mTaskView = taskContainer.getTaskView(); mRecentsView = activity.getOverviewPanel(); - mThumbnailView = taskView.getThumbnail(); + mThumbnailView = taskContainer.getThumbnailView(); mFactory = factory; } @@ -233,11 +252,13 @@ public interface TaskShortcutFactory { } @Override - public SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView taskView) { - SystemShortcut shortcut = super.getShortcut(activity, taskView); + public SystemShortcut getShortcut(BaseDraggingActivity activity, + TaskIdAttributeContainer taskContainer) { + SystemShortcut shortcut = super.getShortcut(activity, taskContainer); if (shortcut != null && FeatureFlags.ENABLE_SPLIT_SELECT.get()) { // Disable if there's only one recent app for split screen - shortcut.setEnabled(taskView.getRecentsView().getTaskViewCount() > 1); + shortcut.setEnabled(taskContainer.getTaskView(). + getRecentsView().getTaskViewCount() > 1); } return shortcut; } @@ -284,7 +305,7 @@ public interface TaskShortcutFactory { } }; - TaskShortcutFactory PIN = (activity, tv) -> { + TaskShortcutFactory PIN = (activity, taskContainer) -> { if (!SystemUiProxy.INSTANCE.get(activity).isActive()) { return null; } @@ -295,7 +316,7 @@ public interface TaskShortcutFactory { // We shouldn't be able to pin while an app is locked. return null; } - return new PinSystemShortcut(activity, tv); + return new PinSystemShortcut(activity, taskContainer); }; class PinSystemShortcut extends SystemShortcut { @@ -304,9 +325,11 @@ public interface TaskShortcutFactory { private final TaskView mTaskView; - public PinSystemShortcut(BaseDraggingActivity target, TaskView tv) { - super(R.drawable.ic_pin, R.string.recent_task_option_pin, target, tv.getItemInfo()); - mTaskView = tv; + public PinSystemShortcut(BaseDraggingActivity target, + TaskIdAttributeContainer taskContainer) { + super(R.drawable.ic_pin, R.string.recent_task_option_pin, target, + taskContainer.getItemInfo()); + mTaskView = taskContainer.getTaskView(); } @Override @@ -320,20 +343,22 @@ public interface TaskShortcutFactory { } } - TaskShortcutFactory INSTALL = (activity, view) -> + TaskShortcutFactory INSTALL = (activity, taskContainer) -> InstantAppResolver.newInstance(activity).isInstantApp(activity, - view.getTask().getTopComponent().getPackageName()) - ? new SystemShortcut.Install(activity, view.getItemInfo()) : null; + taskContainer.getTask().getTopComponent().getPackageName()) + ? new SystemShortcut.Install(activity, taskContainer.getItemInfo()) : null; - TaskShortcutFactory WELLBEING = (activity, view) -> - WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, view.getItemInfo()); + TaskShortcutFactory WELLBEING = (activity, taskContainer) -> + WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, taskContainer.getItemInfo()); - TaskShortcutFactory SCREENSHOT = (activity, tv) -> tv.getThumbnail().getTaskOverlay() - .getScreenshotShortcut(activity, tv.getItemInfo()); + TaskShortcutFactory SCREENSHOT = (activity, taskContainer) -> + taskContainer.getThumbnailView().getTaskOverlay() + .getScreenshotShortcut(activity, taskContainer.getItemInfo()); - TaskShortcutFactory MODAL = (activity, tv) -> { + TaskShortcutFactory MODAL = (activity, taskContainer) -> { if (ENABLE_OVERVIEW_SELECTIONS.get()) { - return tv.getThumbnail().getTaskOverlay().getModalStateSystemShortcut(tv.getItemInfo()); + return taskContainer.getThumbnailView() + .getTaskOverlay().getModalStateSystemShortcut(taskContainer.getItemInfo()); } return null; }; diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index b1b4b54af3..72d3731a7f 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -1,5 +1,8 @@ package com.android.quickstep.views; +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; + import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; @@ -11,7 +14,6 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.util.RunnableList; -import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds; import com.android.launcher3.util.TransformingTouchDelegate; import com.android.quickstep.RecentsModel; @@ -72,7 +74,9 @@ public class GroupedTaskView extends TaskView { super.bind(primary, orientedState); mSecondaryTask = secondary; mTaskIdContainer[1] = secondary.key.id; - mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2); + mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2, + STAGE_POSITION_BOTTOM_OR_RIGHT); + mTaskIdAttributeContainer[0].setStagePosition(STAGE_POSITION_TOP_OR_LEFT); mSnapshotView2.bind(secondary); mSplitBoundsConfig = splitBoundsConfig; } @@ -112,6 +116,10 @@ public class GroupedTaskView extends TaskView { } } + protected boolean showTaskMenuWithContainer(IconView iconView) { + return TaskMenuView.showForTask(mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1]); + } + public void updateSplitBoundsConfig(StagedSplitBounds stagedSplitBounds) { mSplitBoundsConfig = stagedSplitBounds; invalidate(); @@ -143,14 +151,14 @@ public class GroupedTaskView extends TaskView { @Override public RunnableList launchTaskAnimated() { getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask, - SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, null /*callback*/); + STAGE_POSITION_TOP_OR_LEFT, null /*callback*/); return null; } @Override public void launchTask(@NonNull Consumer callback, boolean freezeTaskList) { getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask, - SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, callback); + STAGE_POSITION_TOP_OR_LEFT, callback); } @Override diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java index bfc7eea239..5ddbf87cfd 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java +++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java @@ -16,6 +16,8 @@ package com.android.quickstep.views; +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED; import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA; import android.animation.Animator; @@ -39,6 +41,7 @@ import android.widget.TextView; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.Interpolators; @@ -49,6 +52,7 @@ import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.TaskOverlayFactory; import com.android.quickstep.TaskUtils; import com.android.quickstep.util.TaskCornerRadius; +import com.android.quickstep.views.TaskView.TaskIdAttributeContainer; /** * Contains options for a recent task when long-pressing its icon. @@ -65,6 +69,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange private TextView mTaskName; private AnimatorSet mOpenCloseAnimator; private TaskView mTaskView; + private TaskIdAttributeContainer mTaskContainer; private LinearLayout mOptionLayout; public TaskMenuView(Context context, AttributeSet attrs) { @@ -129,7 +134,8 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange // Inset due to margin PointF additionalInset = pagedOrientationHandler .getAdditionalInsetForTaskMenu(mTaskInsetMargin); - int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx; + DeviceProfile deviceProfile = mActivity.getDeviceProfile(); + int taskTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx; float adjustedY = y + taskTopMargin - additionalInset.y; float adjustedX = x - additionalInset.x; @@ -137,7 +143,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange // NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set, // which would render the X and Y position set here incorrect setPivotX(0); - if (mActivity.getDeviceProfile().overviewShowAsGrid) { + if (deviceProfile.overviewShowAsGrid) { // In tablet, set pivotY to original position without mThumbnailTopMargin adjustment. setPivotY(-taskTopMargin); } else { @@ -145,9 +151,26 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange } setRotation(pagedOrientationHandler.getDegreesRotated()); setX(pagedOrientationHandler.getTaskMenuX(adjustedX, - mTaskView.getThumbnail(), overscrollShift)); + mTaskContainer.getThumbnailView(), overscrollShift)); setY(pagedOrientationHandler.getTaskMenuY( - adjustedY, mTaskView.getThumbnail(), overscrollShift)); + adjustedY, mTaskContainer.getThumbnailView(), overscrollShift)); + + // TODO(b/193432925) temporary menu placement for split screen task menus + TaskIdAttributeContainer[] taskIdAttributeContainers = + mTaskView.getTaskIdAttributeContainers(); + if (taskIdAttributeContainers[0].getStagePosition() != STAGE_POSITION_UNDEFINED) { + if (mTaskContainer.getStagePosition() != STAGE_POSITION_BOTTOM_OR_RIGHT) { + return; + } + Rect r = new Rect(); + mTaskContainer.getThumbnailView().getBoundsOnScreen(r); + if (deviceProfile.isLandscape) { + setX(r.left); + } else { + setY(r.top); + + } + } } public void onRotationChanged() { @@ -162,19 +185,21 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange } } - public static boolean showForTask(TaskView taskView) { - BaseDraggingActivity activity = BaseDraggingActivity.fromContext(taskView.getContext()); + public static boolean showForTask(TaskIdAttributeContainer taskContainer) { + BaseDraggingActivity activity = BaseDraggingActivity.fromContext( + taskContainer.getTaskView().getContext()); final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate( R.layout.task_menu, activity.getDragLayer(), false); - return taskMenuView.populateAndShowForTask(taskView); + return taskMenuView.populateAndShowForTask(taskContainer); } - private boolean populateAndShowForTask(TaskView taskView) { + private boolean populateAndShowForTask(TaskIdAttributeContainer taskContainer) { if (isAttachedToWindow()) { return false; } mActivity.getDragLayer().addView(this); - mTaskView = taskView; + mTaskView = taskContainer.getTaskView(); + mTaskContainer = taskContainer; if (!populateAndLayoutMenu()) { return false; } @@ -192,20 +217,21 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange /** @return true if successfully able to populate task view menu, false otherwise */ private boolean populateAndLayoutMenu() { - if (mTaskView.getTask().icon == null) { + if (mTaskContainer.getTask().icon == null) { // Icon may not be loaded return false; } - addMenuOptions(mTaskView); - orientAroundTaskView(mTaskView); + addMenuOptions(mTaskContainer); + orientAroundTaskView(mTaskContainer); return true; } - private void addMenuOptions(TaskView taskView) { - mTaskName.setText(TaskUtils.getTitle(getContext(), taskView.getTask())); + private void addMenuOptions(TaskIdAttributeContainer taskContainer) { + mTaskName.setText(TaskUtils.getTitle(getContext(), taskContainer.getTask())); mTaskName.setOnClickListener(v -> close(true)); - TaskOverlayFactory.getEnabledShortcuts(taskView, mActivity.getDeviceProfile()) + TaskOverlayFactory.getEnabledShortcuts(mTaskView, mActivity.getDeviceProfile(), + taskContainer) .forEach(this::addMenuOption); } @@ -223,23 +249,25 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange mOptionLayout.addView(menuOptionView); } - private void orientAroundTaskView(TaskView taskView) { - PagedOrientationHandler orientationHandler = taskView.getPagedOrientationHandler(); + private void orientAroundTaskView(TaskIdAttributeContainer taskContainer) { + RecentsView recentsView = mActivity.getOverviewPanel(); + PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler(); measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); orientationHandler.setTaskMenuAroundTaskView(this, mTaskInsetMargin); // Get Position - mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect); + mActivity.getDragLayer().getDescendantRectRelativeToSelf(mTaskView, sTempRect); Rect insets = mActivity.getDragLayer().getInsets(); BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams(); int padding = getResources() .getDimensionPixelSize(R.dimen.task_menu_vertical_padding); - params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail()) - (2 * padding); + params.width = orientationHandler + .getTaskMenuWidth(taskContainer.getThumbnailView()) - (2 * padding); // Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start params.gravity = Gravity.LEFT; setLayoutParams(params); - setScaleX(taskView.getScaleX()); - setScaleY(taskView.getScaleY()); + setScaleX(mTaskView.getScaleX()); + setScaleY(mTaskView.getScaleY()); // Set divider spacing ShapeDrawable divider = new ShapeDrawable(new RectShape()); @@ -272,7 +300,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange revealAnimator.setInterpolator(Interpolators.DEACCEL); mOpenCloseAnimator.playTogether(revealAnimator, ObjectAnimator.ofFloat( - mTaskView.getThumbnail(), DIM_ALPHA, + mTaskContainer.getThumbnailView(), DIM_ALPHA, closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA), ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1)); mOpenCloseAnimator.addListener(new AnimationSuccessListener() { diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 461a89b428..053d07c1c3 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -18,13 +18,6 @@ package com.android.quickstep.views; import static android.view.Gravity.BOTTOM; import static android.view.Gravity.CENTER_HORIZONTAL; -import static android.view.Gravity.CENTER_VERTICAL; -import static android.view.Gravity.END; -import static android.view.Gravity.START; -import static android.view.Gravity.TOP; -import static android.view.Surface.ROTATION_180; -import static android.view.Surface.ROTATION_270; -import static android.view.Surface.ROTATION_90; import static android.widget.Toast.LENGTH_SHORT; import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU; @@ -39,6 +32,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED; import static java.lang.annotation.RetentionPolicy.SOURCE; @@ -58,7 +52,6 @@ import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; import android.view.MotionEvent; -import android.view.Surface; import android.view.TouchDelegate; import android.view.View; import android.view.ViewGroup; @@ -86,6 +79,7 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.ActivityOptionsWrapper; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.RunnableList; +import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.TransformingTouchDelegate; import com.android.launcher3.util.ViewPool.Reusable; @@ -466,7 +460,10 @@ public class TaskView extends FrameLayout implements Reusable { * Builds proto for logging */ public WorkspaceItemInfo getItemInfo() { - final Task task = getTask(); + return getItemInfo(mTask); + } + + protected WorkspaceItemInfo getItemInfo(Task task) { ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key); WorkspaceItemInfo stubInfo = new WorkspaceItemInfo(); stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK; @@ -569,7 +566,8 @@ public class TaskView extends FrameLayout implements Reusable { cancelPendingLoadTasks(); mTask = task; mTaskIdContainer[0] = mTask.key.id; - mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView); + mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView, + STAGE_POSITION_UNDEFINED); mSnapshotView.bind(task); setOrientationState(orientedState); } @@ -825,7 +823,7 @@ public class TaskView extends FrameLayout implements Reusable { } } - private boolean showTaskMenu() { + private boolean showTaskMenu(IconView iconView) { if (getRecentsView().mActivity.isInState(OVERVIEW_SPLIT_SELECT)) { // Don't show menu when selecting second split screen app return true; @@ -837,10 +835,14 @@ public class TaskView extends FrameLayout implements Reusable { } else { mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo()) .log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS); - return TaskMenuView.showForTask(this); + return showTaskMenuWithContainer(iconView); } } + protected boolean showTaskMenuWithContainer(IconView iconView) { + return TaskMenuView.showForTask(mTaskIdAttributeContainer[0]); + } + protected void setIcon(IconView iconView, Drawable icon) { if (icon != null) { iconView.setDrawable(icon); @@ -850,14 +852,14 @@ public class TaskView extends FrameLayout implements Reusable { recentsView.switchToScreenshot( () -> recentsView.finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, - this::showTaskMenu)); + () -> showTaskMenu(iconView))); } else { - showTaskMenu(); + showTaskMenu(iconView); } }); iconView.setOnLongClickListener(v -> { requestDisallowInterceptTouchEvent(true); - return showTaskMenu(); + return showTaskMenu(iconView); }); } else { iconView.setDrawable(null); @@ -1328,8 +1330,9 @@ public class TaskView extends FrameLayout implements Reusable { getContext().getText(R.string.accessibility_close))); final Context context = getContext(); + // TODO(b/200609838) Determine which task to run A11y action on when in split screen for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this, - mActivity.getDeviceProfile())) { + mActivity.getDeviceProfile(), mTaskIdAttributeContainer[0])) { info.addAction(s.createAccessibilityAction(context)); } @@ -1361,8 +1364,9 @@ public class TaskView extends FrameLayout implements Reusable { return true; } + // TODO(b/200609838) Determine which task to run A11y action on when in split screen for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this, - mActivity.getDeviceProfile())) { + mActivity.getDeviceProfile(), mTaskIdAttributeContainer[0])) { if (s.hasHandlerForAction(action)) { s.onClick(this); return true; @@ -1581,20 +1585,40 @@ public class TaskView extends FrameLayout implements Reusable { } public class TaskIdAttributeContainer { - private final TaskThumbnailView thumbnailView; - private final Task task; + private final TaskThumbnailView mThumbnailView; + private final Task mTask; + /** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */ + private @SplitConfigurationOptions.StagePosition int mStagePosition; - public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView) { - this.task = task; - this.thumbnailView = thumbnailView; + public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView, + int stagePosition) { + this.mTask = task; + this.mThumbnailView = thumbnailView; + this.mStagePosition = stagePosition; } public TaskThumbnailView getThumbnailView() { - return thumbnailView; + return mThumbnailView; } public Task getTask() { - return task; + return mTask; + } + + public WorkspaceItemInfo getItemInfo() { + return TaskView.this.getItemInfo(mTask); + } + + public TaskView getTaskView() { + return TaskView.this; + } + + public int getStagePosition() { + return mStagePosition; + } + + void setStagePosition(@SplitConfigurationOptions.StagePosition int stagePosition) { + this.mStagePosition = stagePosition; } } }