Merge "Notify system to report the rounded corners that task bar draws"
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
index f303f31..01d675f 100644
--- a/quickstep/res/layout/overview_panel.xml
+++ b/quickstep/res/layout/overview_panel.xml
@@ -25,13 +25,6 @@
android:clipToPadding="false"
android:visibility="invisible" />
- <com.android.quickstep.views.SplitPlaceholderView
- android:id="@+id/split_placeholder"
- android:layout_width="match_parent"
- android:layout_height="@dimen/split_placeholder_size"
- android:background="@android:color/darker_gray"
- android:visibility="gone" />
-
<include
android:id="@+id/overview_actions_view"
layout="@layout/overview_actions_container" />
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 5ea94e9..c9e33a7 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -228,7 +228,7 @@
<dimen name="taskbar_contextual_buttons_size">35dp</dimen>
<dimen name="taskbar_stashed_size">24dp</dimen>
<dimen name="taskbar_stashed_handle_width">220dp</dimen>
- <dimen name="taskbar_stashed_handle_height">6dp</dimen>
+ <dimen name="taskbar_stashed_handle_height">4dp</dimen>
<dimen name="taskbar_edu_wave_anim_trans_y">25dp</dimen>
<dimen name="taskbar_edu_wave_anim_trans_y_return_overshoot">4dp</dimen>
</resources>
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 2622700..5e8db69 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -20,7 +20,6 @@
import android.animation.Animator;
import android.annotation.ColorInt;
-import android.graphics.Rect;
import android.os.RemoteException;
import android.util.Log;
import android.view.MotionEvent;
@@ -114,13 +113,6 @@
return !mTaskbarLauncherStateController.isAnimatingToLauncher();
}
- @Override
- protected void updateContentInsets(Rect outContentInsets) {
- int contentHeight = mControllers.taskbarStashController.getContentHeight();
- TaskbarDragLayer dragLayer = mControllers.taskbarActivityContext.getDragLayer();
- outContentInsets.top = dragLayer.getHeight() - contentHeight;
- }
-
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 806b390..a918016 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -181,10 +181,13 @@
}
/**
- * Called to update the {@link InsetsInfo#contentInsets}.
+ * Called to update the {@link InsetsInfo#contentInsets}. This is reported to apps but our
+ * internal launcher will ignore these insets.
*/
public void updateContentInsets(Rect outContentInsets) {
- mControllers.uiController.updateContentInsets(outContentInsets);
+ int contentHeight = mControllers.taskbarStashController
+ .getContentHeightToReportToApps();
+ outContentInsets.top = mTaskbarDragLayer.getHeight() - contentHeight;
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 593bfd8..e2ba459 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -375,12 +375,12 @@
// Update the resumed state immediately to ensure a seamless handoff
boolean launcherResumed = !finishedToApp;
- mIconAlignmentForResumedState.updateValue(launcherResumed ? 1 : 0);
-
updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, false);
updateStateForFlag(FLAG_RESUMED, launcherResumed);
applyState();
-
+ // Set this last because applyState() might also animate it.
+ mIconAlignmentForResumedState.cancelAnimation();
+ mIconAlignmentForResumedState.updateValue(launcherResumed ? 1 : 0);
TaskbarStashController controller = mControllers.taskbarStashController;
controller.updateStateForFlag(FLAG_IN_APP, finishedToApp);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 5b275d0..8308d75 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -53,10 +53,17 @@
public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6;
// If we're in an app and any of these flags are enabled, taskbar should be stashed.
- public static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
+ private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
| FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
| FLAG_STASHED_IN_APP_IME;
+ // If any of these flags are enabled, inset apps by our stashed height instead of our unstashed
+ // height. This way the reported insets are consistent even during transitions out of the app.
+ // Currently any flag that causes us to stash in an app is included, except for IME since that
+ // covers the underlying app anyway and thus the app shouldn't change insets.
+ private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP
+ & ~FLAG_STASHED_IN_APP_IME;
+
/**
* How long to stash/unstash when manually invoked via long press.
*/
@@ -239,8 +246,11 @@
return !mIsStashed && (mState & FLAG_IN_APP) != 0;
}
- public int getContentHeight() {
- if (isStashed()) {
+ /**
+ * Returns the height that taskbar will inset when inside apps.
+ */
+ public int getContentHeightToReportToApps() {
+ if (hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
boolean isAnimating = mAnimator != null && mAnimator.isStarted();
return mControllers.stashedHandleViewController.isStashedHandleVisible() || isAnimating
? mStashedHeight : 0;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index f6bc785..abad906 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.taskbar;
-import android.graphics.Rect;
import android.view.View;
import androidx.annotation.CallSuper;
@@ -49,8 +48,6 @@
return true;
}
- protected void updateContentInsets(Rect outContentInsets) { }
-
protected void onStashedInAppChanged() { }
public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 1a901f1..0e5282a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -74,6 +74,7 @@
import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.widget.Toast;
+import android.window.PictureInPictureSurfaceTransaction;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -90,6 +91,7 @@
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.tracing.InputConsumerProto;
import com.android.launcher3.tracing.SwipeHandlerProto;
+import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.BaseActivityInterface.AnimationFactory;
@@ -97,7 +99,6 @@
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActivityInitListener;
-import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.InputConsumerProxy;
import com.android.quickstep.util.InputProxyHandlerFactory;
@@ -1261,7 +1262,8 @@
HomeAnimationFactory homeAnimFactory =
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
runningTaskTarget);
- mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
+ mIsSwipingPipToHome = !mIsSwipeForStagedSplit
+ && homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
final RectFSpringAnim[] windowAnim;
if (mIsSwipingPipToHome) {
mSwipePipToHomeAnimator = createWindowAnimationToPip(
@@ -1728,7 +1730,7 @@
// If there are no targets or the animation not started, then there is nothing to finish
mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
} else {
- maybeFinishSwipePipToHome();
+ maybeFinishSwipeToHome();
finishRecentsControllerToHome(
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
@@ -1737,10 +1739,11 @@
}
/**
- * Resets the {@link #mIsSwipingPipToHome} and notifies SysUI that transition is finished
- * if applicable. This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
+ * Notifies SysUI that transition is finished if applicable and also pass leash transactions
+ * from Launcher to WM.
+ * This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
*/
- private void maybeFinishSwipePipToHome() {
+ private void maybeFinishSwipeToHome() {
if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
mSwipePipToHomeAnimator.getComponentName(),
@@ -1751,6 +1754,18 @@
mSwipePipToHomeAnimator.getFinishTransaction(),
mSwipePipToHomeAnimator.getContentOverlay());
mIsSwipingPipToHome = false;
+ } else if (mIsSwipeForStagedSplit) {
+ // Transaction to hide the task to avoid flicker for entering PiP from split-screen.
+ PictureInPictureSurfaceTransaction tx =
+ new PictureInPictureSurfaceTransaction.Builder()
+ .setAlpha(0f)
+ .build();
+ int[] taskIds =
+ LauncherSplitScreenListener.INSTANCE.getNoCreate().getRunningSplitTaskIds();
+ for (int taskId : taskIds) {
+ mRecentsAnimationController.setFinishTaskTransaction(taskId,
+ tx, null /* overlay */);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/OrientationRectF.java b/quickstep/src/com/android/quickstep/OrientationRectF.java
index 59a202c..aa01b05 100644
--- a/quickstep/src/com/android/quickstep/OrientationRectF.java
+++ b/quickstep/src/com/android/quickstep/OrientationRectF.java
@@ -66,7 +66,7 @@
return applyTransform(event, deltaRotation(mRotation, currentRotation), forceTransform);
}
- private boolean applyTransform(MotionEvent event, int deltaRotation, boolean forceTransform) {
+ public boolean applyTransform(MotionEvent event, int deltaRotation, boolean forceTransform) {
mTmpMatrix.reset();
postDisplayRotation(deltaRotation, mHeight, mWidth, mTmpMatrix);
if (forceTransform) {
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index ecff4f1..d2d3ba3 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -22,6 +22,7 @@
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_UP;
+import static com.android.launcher3.states.RotationHelper.deltaRotation;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.RectF;
@@ -358,7 +359,18 @@
if (mLastRectTouched == null) {
return;
}
- mLastRectTouched.applyTransformFromRotation(event, mCurrentDisplay.rotation, true);
+ if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ if (event.getSurfaceRotation() != mActiveTouchRotation) {
+ // With Shell transitions, we should rotated to the orientation at the start
+ // of the gesture not the current display rotation which will happen early
+ mLastRectTouched.applyTransform(event,
+ deltaRotation(event.getSurfaceRotation(), mActiveTouchRotation),
+ true);
+ }
+ } else {
+ mLastRectTouched.applyTransformFromRotation(event, mCurrentDisplay.rotation,
+ true);
+ }
break;
}
case ACTION_CANCEL:
@@ -366,7 +378,18 @@
if (mLastRectTouched == null) {
return;
}
- mLastRectTouched.applyTransformFromRotation(event, mCurrentDisplay.rotation, true);
+ if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ if (event.getSurfaceRotation() != mActiveTouchRotation) {
+ // With Shell transitions, we should rotated to the orientation at the start
+ // of the gesture not the current display rotation which will happen early
+ mLastRectTouched.applyTransform(event,
+ deltaRotation(event.getSurfaceRotation(), mActiveTouchRotation),
+ true);
+ }
+ } else {
+ mLastRectTouched.applyTransformFromRotation(event, mCurrentDisplay.rotation,
+ true);
+ }
mLastRectTouched = null;
break;
}
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index b031c47..a12a670 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -117,8 +117,8 @@
secondaryTaskTarget = targets.findTask(splitIds[1]);
mStagedSplitBounds = new StagedSplitBounds(
- primaryTaskTarget.screenSpaceBounds,
- secondaryTaskTarget.screenSpaceBounds, splitIds[0], splitIds[1]);
+ primaryTaskTarget.startScreenSpaceBounds,
+ secondaryTaskTarget.startScreenSpaceBounds, splitIds[0], splitIds[1]);
mRemoteTargetHandles[0].mTransformParams.setTargetSet(
createRemoteAnimationTargetsForTarget(primaryTaskTarget, targets));
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 50b69dc..ff175f1 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -24,14 +24,22 @@
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
+import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
+import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
+import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL;
+import android.util.FloatProperty;
+import android.util.Pair;
+
+import androidx.annotation.NonNull;
+
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -100,5 +108,31 @@
setter.setViewBackgroundColor(mActivity.getScrimView(), state.getScrimColor(mActivity),
config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
+
+ RecentsState currentState = mActivity.getStateManager().getState();
+ if (isSplitSelectionState(state) && !isSplitSelectionState(currentState)) {
+ setter.add(mRecentsView.createSplitSelectInitAnimation().buildAnim());
+ }
+
+ Pair<FloatProperty, FloatProperty> taskViewsFloat =
+ mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset(
+ TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
+ mActivity.getDeviceProfile());
+ setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
+ if (isSplitSelectionState(state)) {
+ mRecentsView.applySplitPrimaryScrollOffset();
+ setter.setFloat(mRecentsView, taskViewsFloat.first,
+ mRecentsView.getSplitSelectTranslation(), LINEAR);
+ } else {
+ mRecentsView.resetSplitPrimaryScrollOffset();
+ setter.setFloat(mRecentsView, taskViewsFloat.first, 0, LINEAR);
+ }
+ }
+
+ /**
+ * @return true if {@param toState} is {@link RecentsState#OVERVIEW_SPLIT_SELECT}
+ */
+ private boolean isSplitSelectionState(@NonNull RecentsState toState) {
+ return toState == OVERVIEW_SPLIT_SELECT;
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 5b4eb8b..69da977 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -19,12 +19,12 @@
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
+import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
-import android.content.res.Configuration;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -35,6 +35,7 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.FallbackActivityInterface;
import com.android.quickstep.GestureState;
import com.android.quickstep.RecentsActivity;
@@ -208,6 +209,13 @@
}
@Override
+ public void initiateSplitSelect(TaskView taskView,
+ @SplitConfigurationOptions.StagePosition int stagePosition) {
+ super.initiateSplitSelect(taskView, stagePosition);
+ mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
+ }
+
+ @Override
public void onStateTransitionStart(RecentsState toState) {
setOverviewStateEnabled(true);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
@@ -246,12 +254,4 @@
// Do not let touch escape to siblings below this view.
return result || mActivity.getStateManager().getState().overviewUi();
}
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
-
- // Reset modal state if full configuration changes
- setModalStateEnabled(false);
- }
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index 917b58a..15feb18 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -51,6 +51,8 @@
FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN | FLAG_OVERVIEW_UI);
public static final RecentsState HOME = new RecentsState(3, 0);
public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0);
+ public static final RecentsState OVERVIEW_SPLIT_SELECT = new RecentsState(5,
+ FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_OVERVIEW_UI);
public final int ordinal;
private final int mFlags;
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 8ccab71..ae8e45a 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -52,6 +52,7 @@
import com.android.launcher3.util.SettingsCache;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.views.TaskView;
import java.lang.annotation.Retention;
@@ -340,6 +341,11 @@
@SurfaceRotation
public int getDisplayRotation() {
+ if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ // When shell transitions are enabled, both the display and activity rotations should
+ // be the same once the gesture starts
+ return mRecentsActivityRotation;
+ }
return mDisplayRotation;
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index f676091..f66a6de 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -44,6 +44,7 @@
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -170,7 +171,7 @@
* Sets the targets which the simulator will control
*/
public void setPreview(RemoteAnimationTargetCompat runningTarget) {
- setPreviewBounds(runningTarget.screenSpaceBounds, runningTarget.contentInsets);
+ setPreviewBounds(runningTarget.startScreenSpaceBounds, runningTarget.contentInsets);
}
/**
@@ -304,7 +305,13 @@
mOrientationStateId = mOrientationState.getStateId();
getFullScreenScale();
- mThumbnailData.rotation = mOrientationState.getDisplayRotation();
+ if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ // With shell transitions, the display is rotated early so we need to actually use
+ // the rotation when the gesture starts
+ mThumbnailData.rotation = mOrientationState.getTouchRotation();
+ } else {
+ mThumbnailData.rotation = mOrientationState.getDisplayRotation();
+ }
// mIsRecentsRtl is the inverse of TaskView RTL.
boolean isRtlEnabled = !mIsRecentsRtl;
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 0cea45e..18ab3bb 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -17,8 +17,9 @@
import androidx.annotation.Nullable;
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InsettableFrameLayout;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -43,7 +44,7 @@
private SplitPlaceholderView mSplitPlaceholderView;
private RectF mStartingPosition;
- private final Launcher mLauncher;
+ private final BaseDraggingActivity mActivity;
private final boolean mIsRtl;
private final Rect mOutline = new Rect();
private PagedOrientationHandler mOrientationHandler;
@@ -59,7 +60,7 @@
public FloatingTaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mLauncher = Launcher.getLauncher(context);
+ mActivity = BaseActivity.fromContext(context);
mIsRtl = Utilities.isRtl(getResources());
}
@@ -114,7 +115,7 @@
public void updateInitialPositionForView(TaskView originalView) {
View thumbnail = originalView.getThumbnail();
Rect viewBounds = new Rect(0, 0, thumbnail.getWidth(), thumbnail.getHeight());
- Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), thumbnail, viewBounds,
+ Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), thumbnail, viewBounds,
true /* ignoreTransform */, null /* recycle */,
mStartingPosition);
mStartingPosition.offset(originalView.getTranslationX(), originalView.getTranslationY());
@@ -161,7 +162,7 @@
// Position the floating view exactly on top of the original
lp.topMargin = Math.round(pos.top);
if (mIsRtl) {
- lp.setMarginStart(mLauncher.getDeviceProfile().widthPx - Math.round(pos.right));
+ lp.setMarginStart(mActivity.getDeviceProfile().widthPx - Math.round(pos.right));
} else {
lp.setMarginStart(Math.round(pos.left));
}
@@ -174,7 +175,7 @@
public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds,
View viewToCover, boolean fadeWithThumbnail) {
- final BaseDragLayer dragLayer = mLauncher.getDragLayer();
+ final BaseDragLayer dragLayer = mActivity.getDragLayer();
int[] dragLayerBounds = new int[2];
dragLayer.getLocationOnScreen(dragLayerBounds);
SplitOverlayProperties prop = new SplitOverlayProperties(endBounds,
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6b7d8a5..e0395ea 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -168,15 +168,4 @@
super.initiateSplitSelect(taskView, stagePosition);
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
}
-
- @Override
- protected void onOrientationChanged() {
- super.onOrientationChanged();
- // If overview is in modal state when rotate, reset it to overview state without running
- // animation.
- setModalStateEnabled(false);
- if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
- onRotateInSplitSelectionState();
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ed238d8..c5b191e 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1264,7 +1264,7 @@
@Override
protected void onNotSnappingToPageInFreeScroll() {
int finalPos = mScroller.getFinalX();
- if (!showAsGrid() && finalPos > mMinScroll && finalPos < mMaxScroll) {
+ if (finalPos > mMinScroll && finalPos < mMaxScroll) {
int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1);
int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0);
@@ -1278,6 +1278,19 @@
? mMaxScroll
: getScrollForPage(mNextPage);
+ if (showAsGrid()) {
+ if (isSplitSelectionActive()) {
+ return;
+ }
+ TaskView taskView = getTaskViewAt(mNextPage);
+ // Only snap to fully visible focused task.
+ if (taskView == null
+ || !taskView.isFocusedTask()
+ || !isTaskViewFullyVisible(taskView)) {
+ return;
+ }
+ }
+
mScroller.setFinalX(pageSnapped);
// Ensure the scroll/snap doesn't happen too fast;
int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION
@@ -1640,7 +1653,13 @@
setCurrentPage(mCurrentPage);
}
- protected void onOrientationChanged() {
+ private void onOrientationChanged() {
+ // If overview is in modal state when rotate, reset it to overview state without running
+ // animation.
+ setModalStateEnabled(false);
+ if (isSplitSelectionActive()) {
+ onRotateInSplitSelectionState();
+ }
}
// Update task size and padding that are dependent on DeviceProfile and insets.
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 467d225..ab29972 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -677,7 +677,7 @@
* second app. {@code false} otherwise
*/
private boolean confirmSecondSplitSelectApp() {
- boolean isSelectingSecondSplitApp = mActivity.isInState(OVERVIEW_SPLIT_SELECT);
+ boolean isSelectingSecondSplitApp = getRecentsView().isSplitSelectionActive();
if (isSelectingSecondSplitApp) {
getRecentsView().confirmSplitSelect(this);
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 7c503be..237e426 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -37,6 +37,7 @@
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.OverviewActions;
import com.android.launcher3.tapl.OverviewTask;
+import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.ui.TaplTestsLauncher3;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
@@ -321,7 +322,8 @@
@Test
@PortraitLandscape
public void testOverviewForTablet() throws Exception {
- if (!mLauncher.isTablet()) {
+ // TODO(b/210158657): Re-enable for OOP
+ if (!mLauncher.isTablet() || !TestHelpers.isInLauncherProcess()) {
return;
}
for (int i = 2; i <= 14; i++) {
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index b4bb43e..08698e7 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -25,7 +25,8 @@
launcher:numFolderColumns="3"
launcher:numHotseatIcons="3"
launcher:dbFile="launcher_3_by_3.db"
- launcher:defaultLayoutId="@xml/default_workspace_3x3" >
+ launcher:defaultLayoutId="@xml/default_workspace_3x3"
+ launcher:deviceCategory="phone|multi_display" >
<display-option
launcher:name="Super Short Stubby"
@@ -53,7 +54,8 @@
launcher:numFolderColumns="4"
launcher:numHotseatIcons="4"
launcher:dbFile="launcher_4_by_4.db"
- launcher:defaultLayoutId="@xml/default_workspace_4x4" >
+ launcher:defaultLayoutId="@xml/default_workspace_4x4"
+ launcher:deviceCategory="phone|multi_display" >
<display-option
launcher:name="Short Stubby"
@@ -105,7 +107,8 @@
launcher:numFolderColumns="4"
launcher:numHotseatIcons="5"
launcher:dbFile="launcher.db"
- launcher:defaultLayoutId="@xml/default_workspace_5x5" >
+ launcher:defaultLayoutId="@xml/default_workspace_5x5"
+ launcher:deviceCategory="phone|multi_display" >
<display-option
launcher:name="Large Phone"
@@ -143,7 +146,7 @@
launcher:numAllAppsColumns="6"
launcher:dbFile="launcher_6_by_5.db"
launcher:defaultLayoutId="@xml/default_workspace_6x5"
- launcher:deviceCategory="tablet">
+ launcher:deviceCategory="tablet" >
<display-option
launcher:name="Tablet"
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index f772453..624afe1 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -395,7 +395,13 @@
}
overviewActionsMarginThreeButtonPx = res.getDimensionPixelSize(
R.dimen.overview_actions_margin_three_button);
- overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
+ // Grid task's top margin is only overviewTaskIconSizePx + overviewTaskMarginGridPx, but
+ // overviewTaskThumbnailTopMarginPx is applied to all TaskThumbnailView, so exclude the
+ // extra margin when calculating row spacing.
+ int extraTopMargin = overviewTaskThumbnailTopMarginPx - overviewTaskIconSizePx
+ - overviewTaskMarginGridPx;
+ overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing)
+ - extraTopMargin;
overviewGridSideMargin = isLandscape
? res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_landscape)
: res.getDimensionPixelSize(R.dimen.overview_grid_side_margin_portrait);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index e9725cb..801a31d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1639,6 +1639,8 @@
AbstractFloatingView.closeOpenViews(this, false, TYPE_ALL & ~TYPE_REBIND_SAFE);
finishAutoCancelActionMode();
+ DragView.removeAllViews(this);
+
if (mPendingRequestArgs != null) {
outState.putParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS, mPendingRequestArgs);
}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index 64f1d95..e59eac8 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -16,6 +16,7 @@
private static final String XML = ".xml";
public static final String LAUNCHER_DB = "launcher.db";
+ public static final String LAUNCHER_6_BY_5_DB = "launcher_6_by_5.db";
public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db";
public static final String LAUNCHER_4_BY_4_DB = "launcher_4_by_4.db";
public static final String LAUNCHER_3_BY_3_DB = "launcher_3_by_3.db";
@@ -32,6 +33,7 @@
public static final List<String> GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList(
LAUNCHER_DB,
+ LAUNCHER_6_BY_5_DB,
LAUNCHER_4_BY_5_DB,
LAUNCHER_4_BY_4_DB,
LAUNCHER_3_BY_3_DB,
diff --git a/src/com/android/launcher3/anim/PropertySetter.java b/src/com/android/launcher3/anim/PropertySetter.java
index 729523f..8d77b4b 100644
--- a/src/com/android/launcher3/anim/PropertySetter.java
+++ b/src/com/android/launcher3/anim/PropertySetter.java
@@ -16,6 +16,7 @@
package com.android.launcher3.anim;
+import android.animation.Animator;
import android.animation.TimeInterpolator;
import android.util.FloatProperty;
import android.util.IntProperty;
@@ -64,4 +65,9 @@
TimeInterpolator interpolator) {
property.setValue(target, value);
}
+
+ default void add(Animator animatorSet) {
+ animatorSet.setDuration(0);
+ animatorSet.start();
+ }
}
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 8313571..4588a04 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -564,4 +564,19 @@
iv.setImageDrawable(drawable);
return iv;
}
+
+ /**
+ * Removes any stray DragView from the DragLayer.
+ */
+ public static void removeAllViews(ActivityContext activity) {
+ BaseDragLayer dragLayer = activity.getDragLayer();
+ // Iterate in reverse order. DragView is added later to the dragLayer,
+ // and will be one of the last views.
+ for (int i = dragLayer.getChildCount() - 1; i >= 0; i--) {
+ View child = dragLayer.getChildAt(i);
+ if (child instanceof DragView) {
+ dragLayer.removeView(child);
+ }
+ }
+ }
}
diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java
index 01ebc53..fa11d4e 100644
--- a/src/com/android/launcher3/model/DeviceGridState.java
+++ b/src/com/android/launcher3/model/DeviceGridState.java
@@ -17,7 +17,6 @@
package com.android.launcher3.model;
import static com.android.launcher3.InvariantDeviceProfile.DeviceType;
-import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY;
import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_2;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_3;
@@ -31,7 +30,6 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
-import com.android.launcher3.util.IntSet;
import java.util.Locale;
import java.util.Objects;
@@ -45,13 +43,6 @@
public static final String KEY_HOTSEAT_COUNT = "migration_src_hotseat_count";
public static final String KEY_DEVICE_TYPE = "migration_src_device_type";
- private static final IntSet COMPATIBLE_TYPES = IntSet.wrap(TYPE_PHONE, TYPE_MULTI_DISPLAY);
-
- public static boolean deviceTypeCompatible(@DeviceType int typeA, @DeviceType int typeB) {
- return typeA == typeB
- || (COMPATIBLE_TYPES.contains(typeA) && COMPATIBLE_TYPES.contains(typeB));
- }
-
private final String mGridSizeString;
private final int mNumHotseat;
private final @DeviceType int mDeviceType;
@@ -123,7 +114,6 @@
if (this == other) return true;
if (other == null) return false;
return mNumHotseat == other.mNumHotseat
- && deviceTypeCompatible(mDeviceType, other.mDeviceType)
&& Objects.equals(mGridSizeString, other.mGridSizeString);
}
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 4c0930b..d994dbe 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -87,12 +87,6 @@
}
private static boolean performRestore(Context context, DatabaseHelper helper) {
- if (!DeviceGridState.deviceTypeCompatible(
- new DeviceGridState(LauncherAppState.getIDP(context)).getDeviceType(),
- Utilities.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE))) {
- // DO NOT restore if the device types are incompatible.
- return false;
- }
SQLiteDatabase db = helper.getWritableDatabase();
try (SQLiteTransaction t = new SQLiteTransaction(db)) {
RestoreDbTask task = new RestoreDbTask();
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index c0ec9d8..06313e7 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -88,7 +88,6 @@
private IconLoadResult mIconLoadResult;
- // Draw the drawable of the BubbleTextView behind ClipIconView to reveal the built in shadow.
private View mBtvDrawable;
private ClipIconView mClipIconView;
@@ -347,10 +346,23 @@
mClipIconView.setLayoutParams(clipViewLp);
}
- if (!mIsOpening && btvIcon != null) {
+ setOriginalDrawableBackground(btvIcon);
+ invalidate();
+ }
+
+ /**
+ * Draws the drawable of the BubbleTextView behind ClipIconView
+ *
+ * This is used to:
+ * - Have icon displayed while Adaptive Icon is loading
+ * - Displays the built in shadow to ensure a clean handoff
+ *
+ * Allows nullable as this may be cleared when drawing is deferred to ClipIconView.
+ */
+ private void setOriginalDrawableBackground(@Nullable Drawable btvIcon) {
+ if (!mIsOpening) {
mBtvDrawable.setBackground(btvIcon);
}
- invalidate();
}
/**
@@ -455,7 +467,9 @@
@Override
public void onAnimationStart(Animator animator) {
- if (mIconLoadResult != null && mIconLoadResult.isIconLoaded) {
+ if ((mIconLoadResult != null && mIconLoadResult.isIconLoaded)
+ || (!mIsOpening && mBtvDrawable.getBackground() != null)) {
+ // No need to wait for icon load since we can display the BubbleTextView drawable.
setVisibility(View.VISIBLE);
}
if (!mIsOpening && mOriginalIcon != null) {
@@ -518,6 +532,7 @@
IconLoadResult result = new IconLoadResult(info,
btvIcon == null ? false : btvIcon.isThemed());
+ result.btvDrawable = btvIcon;
final long fetchIconId = sFetchIconId++;
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
@@ -556,6 +571,7 @@
view.mIconLoadResult = fetchIcon(launcher, originalView,
(ItemInfo) originalView.getTag(), isOpening);
}
+ view.setOriginalDrawableBackground(view.mIconLoadResult.btvDrawable);
}
sIconLoadResult = null;
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 19dca45..075505e 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -149,7 +149,7 @@
}
sDumpWasGenerated = true;
Log.d("b/195319692", "sDumpWasGenerated := true", new Exception());
- result = "memory dump filename: " + fileName;
+ result = "saved memory dump as an artifact";
} catch (Throwable e) {
Log.e(TAG, "dumpHprofData failed", e);
result = "failed to save memory dump";