diff --git a/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml b/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml index ef272ed806..686189ea81 100644 --- a/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml +++ b/quickstep/recents_ui_overrides/res/layout/fallback_recents_activity.xml @@ -28,4 +28,9 @@ android:clipToPadding="false" android:outlineProvider="none" android:theme="@style/HomeScreenElementTheme" /> + + + diff --git a/quickstep/recents_ui_overrides/res/layout/overview_panel.xml b/quickstep/recents_ui_overrides/res/layout/overview_panel.xml index a572cad273..eac0bfa8eb 100644 --- a/quickstep/recents_ui_overrides/res/layout/overview_panel.xml +++ b/quickstep/recents_ui_overrides/res/layout/overview_panel.xml @@ -1,5 +1,4 @@ - - - - - + android:layout_width="match_parent" + android:layout_height="match_parent" + android:accessibilityPaneTitle="@string/accessibility_recent_apps" + android:clipChildren="false" + android:clipToPadding="false" + android:theme="@style/HomeScreenElementTheme" + android:visibility="invisible" /> diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index 2942bef939..9bc95d7fd6 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -29,6 +29,7 @@ import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS; import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS; @@ -66,6 +67,7 @@ import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Property; import android.util.SparseBooleanArray; +import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -84,6 +86,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; +import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -113,6 +116,7 @@ import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationTargets; import com.android.quickstep.RecentsModel; import com.android.quickstep.RecentsModel.TaskVisualsChangeListener; +import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SystemUiProxy; import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.TaskUtils; @@ -206,7 +210,7 @@ public abstract class RecentsView extends PagedView impl private boolean mDwbToastShown; protected boolean mDisallowScrollToClearAll; private boolean mOverlayEnabled; - private boolean mFreezeViewVisibility; + protected boolean mFreezeViewVisibility; /** * TODO: Call reloadIdNeeded in onTaskStackChanged. @@ -325,6 +329,8 @@ public abstract class RecentsView extends PagedView impl // Keeps track of the index where the first TaskView should be private int mTaskViewStartIndex = 0; + private View mActionsView; + private boolean mGestureRunning = false; private BaseActivity.MultiWindowModeChangedListener mMultiWindowModeChangedListener = (inMultiWindowMode) -> { @@ -383,6 +389,11 @@ public abstract class RecentsView extends PagedView impl int rotation = RotationHelper.getRotationFromDegrees(i); if (mPreviousRotation != rotation) { animateRecentsRotationInPlace(rotation); + if (rotation == 0) { + showActionsView(); + } else { + hideActionsView(); + } mPreviousRotation = rotation; } } @@ -473,6 +484,7 @@ public abstract class RecentsView extends PagedView impl mIPinnedStackAnimationListener); Launcher launcher = Launcher.getLauncher(getContext()); launcher.getRotationHelper().addForcedRotationCallback(mForcedRotationChangedListener); + addActionsView(); } @Override @@ -636,6 +648,7 @@ public abstract class RecentsView extends PagedView impl if (getTaskViewCount() != requiredTaskCount) { if (indexOfChild(mClearAllButton) != -1) { removeView(mClearAllButton); + hideActionsView(); } for (int i = getTaskViewCount(); i < requiredTaskCount; i++) { addView(mTaskViewPool.getView()); @@ -645,6 +658,7 @@ public abstract class RecentsView extends PagedView impl } if (requiredTaskCount > 0) { addView(mClearAllButton); + showActionsView(); } } @@ -684,6 +698,7 @@ public abstract class RecentsView extends PagedView impl if (indexOfChild(mClearAllButton) != -1) { removeView(mClearAllButton); } + hideActionsView(); } public int getTaskViewCount() { @@ -931,6 +946,7 @@ public abstract class RecentsView extends PagedView impl setEnableDrawingLiveTile(false); setRunningTaskHidden(true); setRunningTaskIconScaledDown(true); + mGestureRunning = true; } /** @@ -1000,6 +1016,7 @@ public abstract class RecentsView extends PagedView impl } setRunningTaskHidden(false); animateUpRunningTaskIconScale(); + mGestureRunning = false; } /** @@ -1016,6 +1033,7 @@ public abstract class RecentsView extends PagedView impl addView(taskView, mTaskViewStartIndex); if (wasEmpty) { addView(mClearAllButton); + showActionsView(); } // The temporary running task is only used for the duration between the start of the // gesture and the task list is loaded and applied @@ -1341,6 +1359,7 @@ public abstract class RecentsView extends PagedView impl if (getTaskViewCount() == 0) { removeView(mClearAllButton); + hideActionsView(); startHome(); } else { snapToPageImmediately(pageToSnapTo); @@ -1485,15 +1504,17 @@ public abstract class RecentsView extends PagedView impl } } mClearAllButton.setContentAlpha(mContentAlpha); - int alphaInt = Math.round(alpha * 255); mEmptyMessagePaint.setAlpha(alphaInt); mEmptyIcon.setAlpha(alphaInt); - if (alpha > 0) { setVisibility(VISIBLE); + if (!mGestureRunning) { + showActionsView(); + } } else if (!mFreezeViewVisibility) { setVisibility(GONE); + hideActionsView(); } } @@ -1507,6 +1528,11 @@ public abstract class RecentsView extends PagedView impl if (!mFreezeViewVisibility) { setVisibility(mContentAlpha > 0 ? VISIBLE : GONE); + if (mContentAlpha > 0) { + showActionsView(); + } else { + hideActionsView(); + } } } } @@ -2057,6 +2083,7 @@ public abstract class RecentsView extends PagedView impl void onEmptyMessageUpdated(boolean isEmpty); } + private static class PinnedStackAnimationListener extends IPinnedStackAnimationListener.Stub { private T mActivity; @@ -2072,4 +2099,34 @@ public abstract class RecentsView extends PagedView impl mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS); } } + + private void showActionsView() { + if (mActionsView != null && getTaskViewCount() > 0) { + mActionsView.setVisibility(VISIBLE); + } + } + + private void hideActionsView() { + if (mActionsView != null) { + mActionsView.setVisibility(GONE); + } + } + + private void addActionsView() { + if (mActionsView == null && ENABLE_OVERVIEW_ACTIONS.get() + && SysUINavigationMode.removeShelfFromOverview(mActivity)) { + mActionsView = ((ViewGroup) getParent()).findViewById(R.id.overview_actions_view); + if (mActionsView != null) { + Rect rect = new Rect(); + getTaskSize(rect); + InsettableFrameLayout.LayoutParams layoutParams = + new InsettableFrameLayout.LayoutParams(rect.width(), + getResources().getDimensionPixelSize( + R.dimen.overview_actions_height)); + layoutParams.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; + mActionsView.setLayoutParams(layoutParams); + showActionsView(); + } + } + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index 9150cc76d0..e09e01ff9f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -16,6 +16,20 @@ 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.widget.Toast.LENGTH_SHORT; + +import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION; +import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; +import static com.android.launcher3.anim.Interpolators.LINEAR; +import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; +import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; @@ -39,14 +53,11 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.Toast; -import androidx.annotation.Nullable; - import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.states.RotationHelper; @@ -76,20 +87,6 @@ import java.util.Collections; import java.util.List; import java.util.function.Consumer; -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.widget.Toast.LENGTH_SHORT; -import static com.android.launcher3.QuickstepAppTransitionManagerImpl.RECENTS_LAUNCH_DURATION; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; -import static com.android.launcher3.anim.Interpolators.LINEAR; -import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; -import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview; - /** * A task in the Recents view. */ @@ -173,8 +170,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private final float mWindowCornerRadius; private final BaseDraggingActivity mActivity; - @Nullable private View mActionsView; - private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; private float mFocusTransitionProgress = 1; @@ -193,8 +188,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private float mFooterVerticalOffset = 0; private float mFooterAlpha = 1; private int mStackHeight; - private boolean mHideActionsView; - private PagedOrientationHandler mOrientationHandler; public TaskView(Context context) { this(context, null); @@ -246,18 +239,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { TaskView.LayoutParams thumbnailParams = (LayoutParams) mSnapshotView.getLayoutParams(); thumbnailParams.bottomMargin = LayoutUtils.thumbnailBottomMargin(context); mSnapshotView.setLayoutParams(thumbnailParams); - - - if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(context)) { - mActionsView = mSnapshotView.getTaskOverlay().getActionsView(); - if (mActionsView != null) { - TaskView.LayoutParams params = new TaskView.LayoutParams(LayoutParams.MATCH_PARENT, - getResources().getDimensionPixelSize(R.dimen.overview_actions_height), - BOTTOM); - addView(mActionsView, params); - mActionsView.setAlpha(0); - } - } } public boolean isTaskOverlayModal() { @@ -457,7 +438,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin); LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams(); int rotation = RotationHelper.getDegreesFromRotation(iconRotation); - mHideActionsView = true; switch (iconRotation) { case Surface.ROTATION_90: iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL; @@ -479,13 +459,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { iconParams.gravity = TOP | CENTER_HORIZONTAL; iconParams.leftMargin = iconParams.topMargin = iconParams.rightMargin = iconParams.bottomMargin = 0; - mHideActionsView = false; break; } mSnapshotView.setLayoutParams(snapshotParams); mIconView.setLayoutParams(iconParams); mIconView.setRotation(rotation); - updateActionsViewVisibility(!mHideActionsView); } private void setIconAndDimTransitionProgress(float progress, boolean invert) { @@ -502,11 +480,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconView.setScaleX(scale); mIconView.setScaleY(scale); - - if (mActionsView != null && isRunningTask()) { - mActionsView.setAlpha(scale); - } - mFooterVerticalOffset = 1.0f - scale; for (FooterWrapper footer : mFooters) { if (footer != null) { @@ -597,31 +570,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mMenuView.setScaleX(getScaleX()); mMenuView.setScaleY(getScaleY()); } - - // This is not the proper implementation and will be replaced with a proper layout. - if (mActionsView != null) { - if (mFocusTransitionProgress == 1f) { - mActionsView.setAlpha(1 - curveInterpolation / MAX_PAGE_SCRIM_ALPHA); - } - maintainActionViewPosition(curveScaleForCurveInterpolation); - } - } - private void maintainActionViewPosition(float curveScaleForCurveInterpolation) { - float inverseCurveScaleFactor = curveScaleForCurveInterpolation == 0 ? 0 : - (1f / curveScaleForCurveInterpolation); - mActionsView.setScaleX(inverseCurveScaleFactor); - mActionsView.setScaleY(inverseCurveScaleFactor); - mActionsView.setTranslationX(inverseCurveScaleFactor * (-getX() - + getRecentsView().getScrollX() + getRecentsView().scrollOffsetLeft())); - mActionsView.setTranslationY( - (1f - curveScaleForCurveInterpolation) * (mSnapshotView.getHeight() - + mActionsView.getHeight()) / 2f - + inverseCurveScaleFactor * (-getTranslationY())); - } - - /** * Sets the footer at the specific index and returns the previously set footer. */ @@ -903,7 +853,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mFullscreenProgress = progress; boolean isFullscreen = mFullscreenProgress > 0; mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE); - updateActionsViewVisibility(progress < 1 && !mHideActionsView); setClipChildren(!isFullscreen); setClipToPadding(!isFullscreen); @@ -937,12 +886,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { invalidateOutline(); } - private void updateActionsViewVisibility(boolean isVisible) { - if (mActionsView != null) { - mActionsView.setVisibility(isVisible ? VISIBLE : GONE); - } - } - public boolean isRunningTask() { if (getRecentsView() == null) { return false; @@ -990,5 +933,4 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mScale = scale; } } - } diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java index fa0e840b20..c5d7c95e0b 100644 --- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java @@ -196,7 +196,10 @@ public abstract class BaseQuickstepLauncher extends Launcher if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get() && removeShelfFromOverview(this)) { // Overview is above all other launcher elements, including qsb, so move it to the top. - getOverviewPanelContainer().bringToFront(); + getOverviewPanel().bringToFront(); + if (getActionsView() != null) { + getActionsView().bringToFront(); + } } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java index 174e49b8d2..7481445600 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java @@ -52,10 +52,12 @@ public abstract class BaseRecentsViewStateController implements StateHandler { protected final T mRecentsView; protected final Launcher mLauncher; + protected final View mActionsView; public BaseRecentsViewStateController(@NonNull Launcher launcher) { mLauncher = launcher; mRecentsView = launcher.getOverviewPanel(); + mActionsView = launcher.getActionsView(); } @Override @@ -72,6 +74,10 @@ public abstract class BaseRecentsViewStateController getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0); OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim(); SCRIM_PROGRESS.set(scrim, state.getOverviewScrimAlpha(mLauncher)); + if (mActionsView != null) { + mActionsView.setTranslationX(translationX); + mActionsView.setAlpha(state.overviewUi ? 1f : 0); + } } @Override @@ -118,6 +124,11 @@ public abstract class BaseRecentsViewStateController OverviewScrim scrim = mLauncher.getDragLayer().getOverviewScrim(); setter.setFloat(scrim, SCRIM_PROGRESS, toState.getOverviewScrimAlpha(mLauncher), builder.getInterpolator(ANIM_OVERVIEW_SCRIM_FADE, LINEAR)); + if (mActionsView != null) { + setter.setFloat(mActionsView, View.TRANSLATION_X, translationX, translateXInterpolator); + setter.setFloat(mActionsView, View.ALPHA, toState.overviewUi ? 1 : 0, + builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT)); + } } /** diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml index 6c66897a45..196eb0f1cf 100644 --- a/res/layout/launcher.xml +++ b/res/layout/launcher.xml @@ -44,8 +44,13 @@ layout="@layout/hotseat" /> + android:id="@+id/overview_panel" + layout="@layout/overview_panel" + android:visibility="gone" /> + + diff --git a/res/layout/overview_actions_holder.xml b/res/layout/overview_actions_holder.xml new file mode 100644 index 0000000000..5946bf67ec --- /dev/null +++ b/res/layout/overview_actions_holder.xml @@ -0,0 +1,20 @@ + + + diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml index 7fff711190..2637f038c5 100644 --- a/res/layout/overview_panel.xml +++ b/res/layout/overview_panel.xml @@ -14,9 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d6e8710120..7c85bb7396 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -80,7 +80,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.animation.OvershootInterpolator; -import android.widget.FrameLayout; import android.widget.Toast; import androidx.annotation.Nullable; @@ -274,7 +273,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // UI and state for the overview panel private View mOverviewPanel; - private FrameLayout mOverviewPanelContainer; + private View mActionsView; @Thunk boolean mWorkspaceLoading = true; @@ -1145,8 +1144,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mFocusHandler = mDragLayer.getFocusIndicatorHelper(); mWorkspace = mDragLayer.findViewById(R.id.workspace); mWorkspace.initParentViews(mDragLayer); - mOverviewPanel = findViewById(R.id.overview_panel_recents); - mOverviewPanelContainer = findViewById(R.id.overview_panel_container); + mOverviewPanel = findViewById(R.id.overview_panel); + mActionsView = findViewById(R.id.overview_actions_view); mHotseat = findViewById(R.id.hotseat); mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN @@ -1389,8 +1388,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return (T) mOverviewPanel; } - public FrameLayout getOverviewPanelContainer() { - return mOverviewPanelContainer; + public View getActionsView() { + return mActionsView; } public DropTargetBar getDropTargetBar() { diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 17858a0290..9b12a62bde 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -145,7 +145,7 @@ public final class LauncherInstrumentation { private static final String WORKSPACE_RES_ID = "workspace"; private static final String APPS_RES_ID = "apps_view"; - private static final String OVERVIEW_RES_ID = "overview_panel_recents"; + private static final String OVERVIEW_RES_ID = "overview_panel"; private static final String WIDGETS_RES_ID = "widgets_list_view"; private static final String CONTEXT_MENU_RES_ID = "deep_shortcuts_container"; public static final int WAIT_TIME_MS = 10000;