Merge "Open taskMenu based on TaskIdAttributeContainer" into sc-v2-dev
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 6e2d2a9..38e8e72 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -301,7 +301,8 @@
mActionsView = findViewById(R.id.overview_actions_view);
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
SplitSelectStateController controller =
- new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this));
+ new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
+ getStateManager(), getDepthController());
overviewPanel.init(mActionsView, controller);
mActionsView.setDp(getDeviceProfile());
mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 09a0b7d..d6efc71 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -128,7 +128,8 @@
SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
SplitSelectStateController controller =
- new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this));
+ new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
+ getStateManager(), null /*depthController*/);
mDragLayer.recreateControllers();
mFallbackRecentsView.init(mActionsView, controller);
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 6addfe3..142fafe 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -56,6 +56,7 @@
import android.window.TransitionInfo;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
@@ -72,6 +73,7 @@
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
+import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
@@ -149,10 +151,12 @@
return taskView;
}
- public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
- RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- RemoteAnimationTargetCompat[] nonAppTargets, DepthController depthController,
+ public static void createRecentsWindowAnimator(
+ @NonNull TaskView v, boolean skipViewChanges,
+ @NonNull RemoteAnimationTargetCompat[] appTargets,
+ @NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
+ @NonNull RemoteAnimationTargetCompat[] nonAppTargets,
+ @Nullable DepthController depthController,
PendingAnimation out) {
RecentsView recentsView = v.getRecentsView();
boolean isQuickSwitch = v.isEndQuickswitchCuj();
@@ -418,15 +422,46 @@
finishCallback.run();
}
- /** Legacy version (until shell transitions are enabled) */
- public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull Task initialTask,
+ /**
+ * Legacy version (until shell transitions are enabled)
+ *
+ * If {@param launchingTaskView} is not null, then this will play the tasks launch animation
+ * from the position of the GroupedTaskView (when user taps on the TaskView to start it).
+ * Technically this case should be taken care of by
+ * {@link #composeRecentsSplitLaunchAnimatorLegacy()} below, but the way we launch tasks whether
+ * it's a single task or multiple tasks results in different entry-points.
+ *
+ * If it is null, then it will simply fade in the starting apps and fade out launcher (for the
+ * case where launcher handles animating starting split tasks from app icon) */
+ public static void composeRecentsSplitLaunchAnimatorLegacy(
+ @Nullable GroupedTaskView launchingTaskView,
+ @NonNull Task initialTask,
@NonNull Task secondTask, @NonNull RemoteAnimationTargetCompat[] appTargets,
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
@NonNull RemoteAnimationTargetCompat[] nonAppTargets,
+ @NonNull StateManager stateManager,
+ @Nullable DepthController depthController,
@NonNull Runnable finishCallback) {
+ if (launchingTaskView != null) {
+ AnimatorSet animatorSet = new AnimatorSet();
+ RecentsView recentsView = launchingTaskView.getRecentsView();
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ finishCallback.run();
+ }
+ });
+ composeRecentsLaunchAnimator(animatorSet, launchingTaskView,
+ appTargets, wallpaperTargets, nonAppTargets,
+ true, stateManager,
+ recentsView, depthController);
+ animatorSet.start();
+ return;
+ }
+
final ArrayList<SurfaceControl> openingTargets = new ArrayList<>();
final ArrayList<SurfaceControl> closingTargets = new ArrayList<>();
-
for (RemoteAnimationTargetCompat appTarget : appTargets) {
final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1;
final int mode = appTarget.mode;
@@ -490,7 +525,7 @@
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
@NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
@NonNull StateManager stateManager, @NonNull RecentsView recentsView,
- @NonNull DepthController depthController) {
+ @Nullable DepthController depthController) {
boolean skipLauncherChanges = !launcherClosing;
TaskView taskView = findTaskViewToLaunch(recentsView, v, appTargets);
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 9c6fd3d..8ccab71 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -162,7 +162,7 @@
*/
public void setDeviceProfile(DeviceProfile deviceProfile) {
boolean oldMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
- setFlag(FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY, !deviceProfile.allowRotation);
+ setFlag(FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY, !deviceProfile.isTablet);
if (mListenersInitialized) {
boolean newMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
// If isMultipleOrientationSupportedByDevice is changed, init or destroy listeners
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 41aaa1a..c784d82 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -30,11 +30,18 @@
import android.view.SurfaceControl;
import android.window.TransitionInfo;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.statehandlers.DepthController;
+import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskViewUtils;
+import com.android.quickstep.views.GroupedTaskView;
+import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
@@ -52,23 +59,32 @@
private final Handler mHandler;
private final SystemUiProxy mSystemUiProxy;
+ private final StateManager mStateManager;
+ private final DepthController mDepthController;
private @StagePosition int mStagePosition;
private Task mInitialTask;
private Task mSecondTask;
private Rect mInitialBounds;
private boolean mRecentsAnimationRunning;
+ /** If not null, this is the TaskView we want to launch from */
+ @Nullable
+ private GroupedTaskView mLaunchingTaskView;
- public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
+ public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy,
+ StateManager stateManager,
+ DepthController depthController) {
mHandler = handler;
mSystemUiProxy = systemUiProxy;
+ mStateManager = stateManager;
+ mDepthController = depthController;
}
/**
* To be called after first task selected
*/
- public void setInitialTaskSelect(Task taskView, @StagePosition int stagePosition,
+ public void setInitialTaskSelect(Task task, @StagePosition int stagePosition,
Rect initialBounds) {
- mInitialTask = taskView;
+ mInitialTask = task;
mStagePosition = stagePosition;
mInitialBounds = initialBounds;
}
@@ -76,13 +92,25 @@
/**
* To be called after second task selected
*/
- public void setSecondTaskId(Task taskView, Consumer<Boolean> callback) {
- mSecondTask = taskView;
+ public void setSecondTaskId(Task task, Consumer<Boolean> callback) {
+ mSecondTask = task;
launchTasks(mInitialTask, mSecondTask, mStagePosition, callback,
false /* freezeTaskList */);
}
/**
+ * To be called when we want to launch split pairs from an existing GroupedTaskView.
+ */
+ public void launchTasks(GroupedTaskView groupedTaskView,
+ Consumer<Boolean> callback, boolean freezeTaskList) {
+ mLaunchingTaskView = groupedTaskView;
+ TaskView.TaskIdAttributeContainer[] taskIdAttributeContainers =
+ groupedTaskView.getTaskIdAttributeContainers();
+ launchTasks(taskIdAttributeContainers[0].getTask(), taskIdAttributeContainers[1].getTask(),
+ taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList);
+ }
+
+ /**
* @param stagePosition representing location of task1
*/
public void launchTasks(Task task1, Task task2, @StagePosition int stagePosition,
@@ -169,8 +197,9 @@
RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
Runnable finishedCallback) {
postAsyncCallback(mHandler,
- () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(mInitialTask,
- mSecondTask, apps, wallpapers, nonApps, () -> {
+ () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(
+ mLaunchingTaskView, mInitialTask, mSecondTask, apps, wallpapers,
+ nonApps, mStateManager, mDepthController, () -> {
finishedCallback.run();
if (mSuccessCallback != null) {
mSuccessCallback.accept(true);
@@ -201,6 +230,7 @@
mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
mInitialBounds = null;
mRecentsAnimationRunning = false;
+ mLaunchingTaskView = null;
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index c26837c..325ec04 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -73,6 +73,32 @@
mSplitPlaceholderView.setAlpha(0);
}
+ private void init(StatefulActivity launcher, TaskView originalView, RectF positionOut) {
+ mStartingPosition = positionOut;
+ updateInitialPositionForView(originalView);
+ final InsettableFrameLayout.LayoutParams lp =
+ (InsettableFrameLayout.LayoutParams) getLayoutParams();
+
+ mSplitPlaceholderView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height));
+ positionOut.round(mOutline);
+ setPivotX(0);
+ setPivotY(0);
+
+ // Copy bounds of exiting thumbnail into ImageView
+ TaskThumbnailView thumbnail = originalView.getThumbnail();
+ mImageView.setImageBitmap(thumbnail.getThumbnail());
+ mImageView.setVisibility(VISIBLE);
+
+ mOrientationHandler = originalView.getRecentsView().getPagedOrientationHandler();
+ mSplitPlaceholderView.setIconView(originalView.getIconView(),
+ launcher.getDeviceProfile().overviewTaskIconDrawableSizePx);
+ mSplitPlaceholderView.getIconView().setRotation(mOrientationHandler.getDegreesRotated());
+ }
+
+ /**
+ * Configures and returns a an instance of {@link FloatingTaskView} initially matching the
+ * appearance of {@code originalView}.
+ */
public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
TaskView originalView, RectF positionOut) {
final BaseDragLayer dragLayer = launcher.getDragLayer();
@@ -80,28 +106,7 @@
final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
.inflate(R.layout.floating_split_select_view, parent, false);
- floatingView.mStartingPosition = positionOut;
- floatingView.updateInitialPositionForView(originalView);
- final InsettableFrameLayout.LayoutParams lp =
- (InsettableFrameLayout.LayoutParams) floatingView.getLayoutParams();
-
- floatingView.mSplitPlaceholderView.setLayoutParams(
- new FrameLayout.LayoutParams(lp.width, lp.height));
- positionOut.round(floatingView.mOutline);
- floatingView.setPivotX(0);
- floatingView.setPivotY(0);
-
- // Copy bounds of exiting thumbnail into ImageView
- TaskThumbnailView thumbnail = originalView.getThumbnail();
- floatingView.mImageView.setImageBitmap(thumbnail.getThumbnail());
- floatingView.mImageView.setVisibility(VISIBLE);
-
- floatingView.mOrientationHandler =
- originalView.getRecentsView().getPagedOrientationHandler();
- floatingView.mSplitPlaceholderView.setIconView(originalView.getIconView(),
- launcher.getDeviceProfile().overviewTaskIconDrawableSizePx);
- floatingView.mSplitPlaceholderView.getIconView()
- .setRotation(floatingView.mOrientationHandler.getDegreesRotated());
+ floatingView.init(launcher, originalView, positionOut);
parent.addView(floatingView);
return floatingView;
}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 05bf0f5..4771d1e 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -148,8 +148,8 @@
@Nullable
@Override
public RunnableList launchTaskAnimated() {
- getRecentsView().getSplitPlaceholder().launchTasks(mTask, mSecondaryTask,
- STAGE_POSITION_TOP_OR_LEFT, null /*callback*/,
+ getRecentsView().getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
+ null /*callback*/,
false /* freezeTaskList */);
return null;
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index e64ea90..f2836ca 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -16,13 +16,10 @@
package com.android.launcher3;
-import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-
import static com.android.launcher3.ResourceUtils.pxFromDp;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
-import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -64,7 +61,6 @@
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
public final boolean isTwoPanels;
- public final boolean allowRotation;
// Device properties in current orientation
public final boolean isLandscape;
@@ -244,12 +240,7 @@
availableHeightPx = windowBounds.availableSize.y;
mInfo = info;
- // If the device's pixel density was scaled (usually via settings for A11y), use the
- // original dimensions to determine if rotation is allowed of not.
- float originalSmallestWidth = dpiFromPx(Math.min(widthPx, heightPx), DENSITY_DEVICE_STABLE);
- allowRotation = originalSmallestWidth >= MIN_TABLET_WIDTH;
- // Tablet UI does not support emulated landscape.
- isTablet = allowRotation && info.isTablet(windowBounds);
+ isTablet = info.isTablet(windowBounds);
isPhone = !isTablet;
isTwoPanels = isTablet && useTwoPanels;
@@ -1031,7 +1022,6 @@
writer.println(prefix + "DeviceProfile:");
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
- writer.println(prefix + "\tallowRotation:" + allowRotation);
writer.println(prefix + "\tisTablet:" + isTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index f348a33..0c39632 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -49,6 +49,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import java.util.Collections;
@@ -253,12 +254,13 @@
case ALLOW_ROTATION_PREFERENCE_KEY:
DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get(
getContext()).getDeviceProfile(getContext());
- if (deviceProfile.allowRotation) {
+ if (deviceProfile.isTablet) {
// Launcher supports rotation by default. No need to show this setting.
return false;
}
// Initialize the UI once
- preference.setDefaultValue(false);
+ preference.setDefaultValue(
+ RotationHelper.getAllowRotationDefaultValue(deviceProfile));
return true;
case FLAGS_PREFERENCE_KEY:
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 87871b1..867fd99 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -18,6 +18,10 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
+
+import static com.android.launcher3.Utilities.dpiFromPx;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
@@ -25,7 +29,6 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.UiThreadHelper;
/**
@@ -38,6 +41,17 @@
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
+ /**
+ * Returns the default value of {@link #ALLOW_ROTATION_PREFERENCE_KEY} preference.
+ */
+ public static boolean getAllowRotationDefaultValue(DeviceProfile deviceProfile) {
+ // If the device's pixel density was scaled (usually via settings for A11y), use the
+ // original dimensions to determine if rotation is allowed of not.
+ float originalSmallestWidth = dpiFromPx(
+ Math.min(deviceProfile.widthPx, deviceProfile.heightPx), DENSITY_DEVICE_STABLE);
+ return originalSmallestWidth >= MIN_TABLET_WIDTH;
+ }
+
public static final int REQUEST_NONE = 0;
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
@@ -51,7 +65,7 @@
/**
* Rotation request made by
- * {@link ActivityTracker.SchedulerCallback}.
+ * {@link com.android.launcher3.util.ActivityTracker.SchedulerCallback}.
* This supersedes any other request.
*/
private int mStateHandlerRequest = REQUEST_NONE;
@@ -84,7 +98,7 @@
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
}
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
- mActivity.getDeviceProfile().allowRotation);
+ getAllowRotationDefaultValue(mActivity.getDeviceProfile()));
} else {
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
@@ -98,7 +112,7 @@
if (mDestroyed) return;
boolean wasRotationEnabled = mHomeRotationEnabled;
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
- mActivity.getDeviceProfile().allowRotation);
+ getAllowRotationDefaultValue(mActivity.getDeviceProfile()));
if (mHomeRotationEnabled != wasRotationEnabled) {
notifyChange();
}
@@ -106,7 +120,7 @@
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
- boolean ignoreAutoRotateSettings = dp.allowRotation;
+ boolean ignoreAutoRotateSettings = dp.isTablet;
if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
notifyChange();
@@ -143,7 +157,7 @@
public void initialize() {
if (!mInitialized) {
mInitialized = true;
- setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().allowRotation);
+ setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().isTablet);
mActivity.addOnDeviceProfileChangeListener(this);
notifyChange();
}