Merge "Enabling testQuickSwitchFromApp after causes of flakiness were fixed" into ub-launcher3-master
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index d747bb8..6d105ac 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -71,6 +71,7 @@
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
android:fullBackupOnly="true"
+ android:backupInForeground="true"
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher_home"
diff --git a/OWNERS b/OWNERS
index bf4cd0b..3069afa 100644
--- a/OWNERS
+++ b/OWNERS
@@ -29,5 +29,5 @@
xuqiu@google.com
sreyasr@google.com
-per-file FeatureFlags.java = sunnygoyal@google.com, adamcohen@google.com
-per-file BaseFlags.java = sunnygoyal@google.com, adamcohen@google.com
+per-file FeatureFlags.java, globs = set noparent
+per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, zakcohen@google.com, mrcasey@google.com, adamcohen@google.com, hyunyoungs@google.com
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 ef272ed..686189e 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" />
+
+ <include
+ android:id="@+id/overview_actions_view"
+ layout="@layout/overview_actions_holder" />
+
</com.android.quickstep.fallback.RecentsRootView>
diff --git a/quickstep/recents_ui_overrides/res/layout/overview_panel.xml b/quickstep/recents_ui_overrides/res/layout/overview_panel.xml
index a572cad..eac0bfa 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 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2017 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,17 +13,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.InsettableFrameLayout
+<com.android.quickstep.views.LauncherRecentsView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <com.android.quickstep.views.LauncherRecentsView
- android:id="@+id/overview_panel_recents"
- android:theme="@style/HomeScreenElementTheme"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:accessibilityPaneTitle="@string/accessibility_recent_apps"
- android:visibility="invisible" />
-</com.android.launcher3.InsettableFrameLayout>
+ 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/res/values/dimens.xml b/quickstep/recents_ui_overrides/res/values/dimens.xml
index de97d08..61c576e 100644
--- a/quickstep/recents_ui_overrides/res/values/dimens.xml
+++ b/quickstep/recents_ui_overrides/res/values/dimens.xml
@@ -23,10 +23,4 @@
<!-- Minimum distance to swipe to trigger accessibility gesture -->
<dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen>
-
- <!-- Swipe up to home related -->
- <dimen name="swipe_up_fling_min_visible_change">18dp</dimen>
- <dimen name="swipe_up_y_overshoot">10dp</dimen>
- <dimen name="swipe_up_max_workspace_trans_y">-60dp</dimen>
-
</resources>
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 1d1c7bb..e9ce692 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
-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.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
@@ -32,6 +31,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
+import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -78,18 +78,16 @@
private static final String TAG = "BaseSwipeUpHandler";
protected static final Rect TEMP_RECT = new Rect();
- // Start resisting when swiping past this factor of mTransitionDragLength.
- private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = ENABLE_OVERVIEW_ACTIONS.get()
- ? 2.8f : 1.4f;
- // This is how far down we can scale down, where 0f is full screen and 1f is recents.
- private static final float DRAG_LENGTH_FACTOR_MAX_PULLBACK = ENABLE_OVERVIEW_ACTIONS.get()
- ? 3.6f : 1.8f;
private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL;
// The distance needed to drag to reach the task size in recents.
protected int mTransitionDragLength;
// How much further we can drag past recents, as a factor of mTransitionDragLength.
protected float mDragLengthFactor = 1;
+ // Start resisting when swiping past this factor of mTransitionDragLength.
+ private float mDragLengthFactorStartPullback = 1f;
+ // This is how far down we can scale down, where 0f is full screen and 1f is recents.
+ private float mDragLengthFactorMaxPullback = 1f;
protected final Context mContext;
protected final RecentsAnimationDeviceState mDeviceState;
@@ -161,12 +159,12 @@
} else {
float translation = Math.max(displacement, 0);
shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength;
- if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) {
+ if (shift > mDragLengthFactorStartPullback) {
float pullbackProgress = Utilities.getProgress(shift,
- DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor);
+ mDragLengthFactorStartPullback, mDragLengthFactor);
pullbackProgress = PULLBACK_INTERPOLATOR.getInterpolation(pullbackProgress);
- shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress
- * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK);
+ shift = mDragLengthFactorStartPullback + pullbackProgress
+ * (mDragLengthFactorMaxPullback - mDragLengthFactorStartPullback);
}
}
@@ -344,6 +342,10 @@
// their ability to scale past the target rect.
float dragFactor = (float) dp.heightPx / mTransitionDragLength;
mDragLengthFactor = displayRotation == 0 ? dragFactor : Math.min(1.0f, dragFactor);
+ Pair<Float, Float> dragFactorStartAndMaxProgress =
+ mActivityInterface.getSwipeUpPullbackStartAndMaxProgress();
+ mDragLengthFactorStartPullback = dragFactorStartAndMaxProgress.first;
+ mDragLengthFactorMaxPullback = dragFactorStartAndMaxProgress.second;
}
}
@@ -448,7 +450,7 @@
RotationHelper.mapInverseRectFromNormalOrientation(startRect,
mDp.widthPx, mDp.heightPx, mOrientedState.getDisplayRotation());
}
- RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext.getResources());
+ RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext);
if (isFloatingIconView) {
FloatingIconView fiv = (FloatingIconView) floatingView;
anim.addAnimatorListener(fiv);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index f19ec69..ccc2150 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -38,6 +38,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.UserHandle;
+import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -54,7 +55,6 @@
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.appprediction.PredictionUiStateManager;
-import com.android.launcher3.touch.PortraitPagedViewHandler;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
@@ -80,6 +80,8 @@
public final class LauncherActivityInterface implements BaseActivityInterface<Launcher> {
private Runnable mAdjustInterpolatorsRunnable;
+ private Pair<Float, Float> mSwipeUpPullbackStartAndMaxProgress =
+ BaseActivityInterface.super.getSwipeUpPullbackStartAndMaxProgress();
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
@@ -94,6 +96,11 @@
}
@Override
+ public Pair<Float, Float> getSwipeUpPullbackStartAndMaxProgress() {
+ return mSwipeUpPullbackStartAndMaxProgress;
+ }
+
+ @Override
public void onTransitionCancelled(boolean activityVisible) {
Launcher launcher = getCreatedActivity();
if (launcher == null) {
@@ -385,6 +392,14 @@
return newT <= 1f ? newT : newT + normalizedTranslationY * (newT - 1);
});
};
+
+ // Start pulling back when RecentsView scale is 0.75f, and let it go down to 0.5f.
+ float pullbackStartProgress = (0.75f - fromScaleAndTranslation.scale)
+ / (endScaleAndTranslation.scale - fromScaleAndTranslation.scale);
+ float pullbackMaxProgress = (0.5f - fromScaleAndTranslation.scale)
+ / (endScaleAndTranslation.scale - fromScaleAndTranslation.scale);
+ mSwipeUpPullbackStartAndMaxProgress = new Pair<>(
+ pullbackStartProgress, pullbackMaxProgress);
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
index 682c92c..dde7605 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -17,7 +17,6 @@
import android.animation.Animator;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.RectF;
@@ -106,7 +105,7 @@
private float mMinVisChange;
private float mYOvershoot;
- public RectFSpringAnim(RectF startRect, RectF targetRect, Resources resources) {
+ public RectFSpringAnim(RectF startRect, RectF targetRect, Context context) {
mStartRect = startRect;
mTargetRect = targetRect;
mCurrentCenterX = mStartRect.centerX();
@@ -114,8 +113,9 @@
mTrackingBottomY = startRect.bottom < targetRect.bottom;
mCurrentY = mTrackingBottomY ? mStartRect.bottom : mStartRect.top;
- mMinVisChange = resources.getDimensionPixelSize(R.dimen.swipe_up_fling_min_visible_change);
- mYOvershoot = resources.getDimensionPixelSize(R.dimen.swipe_up_y_overshoot);
+ ResourceProvider rp = DynamicResource.provider(context);
+ mMinVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
+ mYOvershoot = rp.getDimension(R.dimen.swipe_up_y_overshoot);
}
public void onTargetPositionChanged() {
@@ -160,7 +160,7 @@
float endX = mTargetRect.centerX();
float minXValue = Math.min(startX, endX);
float maxXValue = Math.max(startX, endX);
- mRectXAnim = new FlingSpringAnim(this, RECT_CENTER_X, startX, endX,
+ mRectXAnim = new FlingSpringAnim(this, context, RECT_CENTER_X, startX, endX,
velocityPxPerMs.x * 1000, mMinVisChange, minXValue, maxXValue, 1f, onXEndListener);
float startVelocityY = velocityPxPerMs.y * 1000;
@@ -170,13 +170,13 @@
float endY = mTrackingBottomY ? mTargetRect.bottom : mTargetRect.top;
float minYValue = Math.min(startY, endY - mYOvershoot);
float maxYValue = Math.max(startY, endY);
- mRectYAnim = new FlingSpringAnim(this, RECT_Y, startY, endY, startVelocityY,
+ mRectYAnim = new FlingSpringAnim(this, context, RECT_Y, startY, endY, startVelocityY,
mMinVisChange, minYValue, maxYValue, springVelocityFactor, onYEndListener);
float minVisibleChange = Math.abs(1f / mStartRect.height());
ResourceProvider rp = DynamicResource.provider(context);
- float damping = rp.getFloat(R.dimen.swipe_up_rect_damping_ratio);
- float stiffness = rp.getFloat(R.dimen.swipe_up_rect_stiffness);
+ float damping = rp.getFloat(R.dimen.swipe_up_rect_scale_damping_ratio);
+ float stiffness = rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
mRectScaleAnim = new SpringAnimation(this, RECT_SCALE_PROGRESS)
.setSpring(new SpringForce(1f)
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 2942bef..9bc95d7 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_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.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 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.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 @@
private boolean mDwbToastShown;
protected boolean mDisallowScrollToClearAll;
private boolean mOverlayEnabled;
- private boolean mFreezeViewVisibility;
+ protected boolean mFreezeViewVisibility;
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
@@ -325,6 +329,8 @@
// 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 @@
int rotation = RotationHelper.getRotationFromDegrees(i);
if (mPreviousRotation != rotation) {
animateRecentsRotationInPlace(rotation);
+ if (rotation == 0) {
+ showActionsView();
+ } else {
+ hideActionsView();
+ }
mPreviousRotation = rotation;
}
}
@@ -473,6 +484,7 @@
mIPinnedStackAnimationListener);
Launcher launcher = Launcher.getLauncher(getContext());
launcher.getRotationHelper().addForcedRotationCallback(mForcedRotationChangedListener);
+ addActionsView();
}
@Override
@@ -636,6 +648,7 @@
if (getTaskViewCount() != requiredTaskCount) {
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
+ hideActionsView();
}
for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
addView(mTaskViewPool.getView());
@@ -645,6 +658,7 @@
}
if (requiredTaskCount > 0) {
addView(mClearAllButton);
+ showActionsView();
}
}
@@ -684,6 +698,7 @@
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
}
+ hideActionsView();
}
public int getTaskViewCount() {
@@ -931,6 +946,7 @@
setEnableDrawingLiveTile(false);
setRunningTaskHidden(true);
setRunningTaskIconScaledDown(true);
+ mGestureRunning = true;
}
/**
@@ -1000,6 +1016,7 @@
}
setRunningTaskHidden(false);
animateUpRunningTaskIconScale();
+ mGestureRunning = false;
}
/**
@@ -1016,6 +1033,7 @@
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 @@
if (getTaskViewCount() == 0) {
removeView(mClearAllButton);
+ hideActionsView();
startHome();
} else {
snapToPageImmediately(pageToSnapTo);
@@ -1485,15 +1504,17 @@
}
}
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 @@
if (!mFreezeViewVisibility) {
setVisibility(mContentAlpha > 0 ? VISIBLE : GONE);
+ if (mContentAlpha > 0) {
+ showActionsView();
+ } else {
+ hideActionsView();
+ }
}
}
}
@@ -2057,6 +2083,7 @@
void onEmptyMessageUpdated(boolean isEmpty);
}
+
private static class PinnedStackAnimationListener<T extends BaseActivity> extends
IPinnedStackAnimationListener.Stub {
private T mActivity;
@@ -2072,4 +2099,34 @@
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 9150cc7..e09e01f 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.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.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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
mFullscreenProgress = progress;
boolean isFullscreen = mFullscreenProgress > 0;
mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
- updateActionsViewVisibility(progress < 1 && !mHideActionsView);
setClipChildren(!isFullscreen);
setClipToPadding(!isFullscreen);
@@ -937,12 +886,6 @@
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 @@
mScale = scale;
}
}
-
}
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index fa0e840..fb0cd17 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -36,6 +36,7 @@
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.accessibility.SystemActions;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.popup.SystemShortcut;
@@ -53,6 +54,7 @@
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.util.ShelfPeekAnim;
import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import java.util.stream.Stream;
@@ -62,6 +64,8 @@
public abstract class BaseQuickstepLauncher extends Launcher
implements NavigationModeChangeListener {
+ protected SystemActions mSystemActions;
+
/**
* Reusable command for applying the back button alpha on the background thread.
*/
@@ -74,6 +78,7 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mSystemActions = new SystemActions(this);
SysUINavigationMode.Mode mode = SysUINavigationMode.INSTANCE.get(this)
.addModeChangeListener(this);
@@ -132,6 +137,12 @@
}
@Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ mSystemActions.onActivityResult(requestCode);
+ }
+
+ @Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
@@ -148,6 +159,12 @@
}
@Override
+ protected void onUiChangedWhileSleeping() {
+ // Remove the snapshot because the content view may have obvious changes.
+ ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this);
+ }
+
+ @Override
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
if (requestCode != -1) {
@@ -188,6 +205,15 @@
// removes the task itself.
startActivity(ProxyActivityStarter.getLaunchIntent(this, null));
}
+
+ // Register all system actions once they are available
+ mSystemActions.register();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mSystemActions.unregister();
}
@Override
@@ -196,7 +222,10 @@
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/accessibility/SystemActions.java b/quickstep/src/com/android/launcher3/accessibility/SystemActions.java
new file mode 100644
index 0000000..669877f
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/accessibility/SystemActions.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.accessibility;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+
+import android.app.PendingIntent;
+import android.app.RemoteAction;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
+import android.view.accessibility.AccessibilityManager;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.R;
+
+/**
+ * Manages the launcher system actions presented to accessibility services.
+ */
+public class SystemActions {
+
+ /**
+ * System Action ID to show all apps. This ID should follow the ones in
+ * com.android.systemui.accessibility.SystemActions.
+ */
+ private static final int SYSTEM_ACTION_ID_ALL_APPS = 100;
+
+ private Launcher mLauncher;
+ private AccessibilityManager mAccessibilityManager;
+ private RemoteAction mAllAppsAction;
+ private boolean mRegistered;
+
+ public SystemActions(Launcher launcher) {
+ mLauncher = launcher;
+ mAccessibilityManager = (AccessibilityManager) launcher.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ mAllAppsAction = new RemoteAction(
+ Icon.createWithResource(launcher, R.drawable.ic_apps),
+ launcher.getString(R.string.all_apps_label),
+ launcher.getString(R.string.all_apps_label),
+ launcher.createPendingResult(SYSTEM_ACTION_ID_ALL_APPS, new Intent(),
+ 0 /* flags */));
+ }
+
+ public void register() {
+ if (mRegistered) {
+ return;
+ }
+ mAccessibilityManager.registerSystemAction(mAllAppsAction, SYSTEM_ACTION_ID_ALL_APPS);
+ mRegistered = true;
+ }
+
+ public void unregister() {
+ if (!mRegistered) {
+ return;
+ }
+ mAccessibilityManager.unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
+ mRegistered = false;
+ }
+
+ public void onActivityResult(int requestCode) {
+ if (requestCode == SYSTEM_ACTION_ID_ALL_APPS) {
+ showAllApps();
+ }
+ }
+
+ private void showAllApps() {
+ LauncherStateManager stateManager = mLauncher.getStateManager();
+ stateManager.goToState(NORMAL);
+ stateManager.goToState(ALL_APPS);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 174e49b..7481445 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -52,10 +52,12 @@
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 @@
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 @@
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/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 64e053f..1d71fe2 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -20,6 +20,7 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
+import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -50,6 +51,15 @@
int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
+ /**
+ * @return The progress of the swipe where we start resisting the user, where 0 is fullscreen
+ * and 1 is recents. These values should probably be greater than 1 to let the user swipe past
+ * recents before we start resisting them.
+ */
+ default Pair<Float, Float> getSwipeUpPullbackStartAndMaxProgress() {
+ return new Pair<>(1.4f, 1.8f);
+ }
+
void onSwipeUpToRecentsComplete();
default void onSwipeUpToHomeComplete() { }
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 85ef4c6..866836e 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -33,6 +33,7 @@
import android.content.pm.ResolveInfo;
import android.util.SparseIntArray;
+import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.systemui.shared.system.PackageManagerWrapper;
import java.io.PrintWriter;
@@ -44,18 +45,11 @@
* and provide callers the relevant classes.
*/
public final class OverviewComponentObserver {
- private final BroadcastReceiver mUserPreferenceChangeReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateOverviewTargets();
- }
- };
- private final BroadcastReceiver mOtherHomeAppUpdateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- updateOverviewTargets();
- }
- };
+ private final BroadcastReceiver mUserPreferenceChangeReceiver =
+ new SimpleBroadcastReceiver(this::updateOverviewTargets);
+ private final BroadcastReceiver mOtherHomeAppUpdateReceiver =
+ new SimpleBroadcastReceiver(this::updateOverviewTargets);
+
private final Context mContext;
private final RecentsAnimationDeviceState mDeviceState;
private final Intent mCurrentHomeIntent;
@@ -106,6 +100,10 @@
}
}
+ private void updateOverviewTargets(Intent unused) {
+ updateOverviewTargets();
+ }
+
/**
* Update overview intent and {@link BaseActivityInterface} based off the current launcher home
* component.
@@ -131,11 +129,8 @@
mOverviewIntent = mMyHomeIntent;
mCurrentHomeIntent.setComponent(mMyHomeIntent.getComponent());
- if (mUpdateRegisteredPackage != null) {
- // Remove any update listener as we don't care about other packages.
- mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
- mUpdateRegisteredPackage = null;
- }
+ // Remove any update listener as we don't care about other packages.
+ unregisterOtherHomeAppUpdateReceiver();
} else {
// The default home app is a different launcher. Use the fallback Overview instead.
@@ -149,13 +144,9 @@
// Listen for package updates of this app (and remove any previously attached
// package listener).
if (defaultHome == null) {
- if (mUpdateRegisteredPackage != null) {
- mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
- }
+ unregisterOtherHomeAppUpdateReceiver();
} else if (!defaultHome.getPackageName().equals(mUpdateRegisteredPackage)) {
- if (mUpdateRegisteredPackage != null) {
- mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
- }
+ unregisterOtherHomeAppUpdateReceiver();
mUpdateRegisteredPackage = defaultHome.getPackageName();
mContext.registerReceiver(mOtherHomeAppUpdateReceiver, getPackageFilter(
@@ -170,7 +161,10 @@
*/
public void onDestroy() {
mContext.unregisterReceiver(mUserPreferenceChangeReceiver);
+ unregisterOtherHomeAppUpdateReceiver();
+ }
+ private void unregisterOtherHomeAppUpdateReceiver() {
if (mUpdateRegisteredPackage != null) {
mContext.unregisterReceiver(mOtherHomeAppUpdateReceiver);
mUpdateRegisteredPackage = null;
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index 9a053f2..ccfa3fc 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -3,8 +3,6 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-import static com.android.launcher3.util.rule.TestStabilityRule.UNBUNDLED_POSTSUBMIT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -13,12 +11,12 @@
import android.app.PendingIntent;
import android.app.usage.UsageStatsManager;
import android.content.Intent;
+import android.os.Build;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
-import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.views.DigitalWellBeingToast;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -35,9 +33,10 @@
resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
@Test
- // b/150303529
- @TestStabilityRule.Stability(flavors = UNBUNDLED_POSTSUBMIT | PLATFORM_POSTSUBMIT)
public void testToast() throws Exception {
+ // b/150303529
+ if (Build.MODEL.contains("Cuttlefish")) return;
+
startAppFast(CALCULATOR_PACKAGE);
final UsageStatsManager usageStatsManager =
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 6c66897..196eb0f 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -44,8 +44,13 @@
layout="@layout/hotseat" />
<include
- android:id="@+id/overview_panel_container"
- layout="@layout/overview_panel"/>
+ android:id="@+id/overview_panel"
+ layout="@layout/overview_panel"
+ android:visibility="gone" />
+
+ <include
+ android:id="@+id/overview_actions_view"
+ layout="@layout/overview_actions_holder" />
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
diff --git a/res/layout/overview_actions_holder.xml b/res/layout/overview_actions_holder.xml
new file mode 100644
index 0000000..5946bf6
--- /dev/null
+++ b/res/layout/overview_actions_holder.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<Space
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dp"
+ android:layout_height="0dp" />
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index 7fff711..2637f03 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.
-->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/overview_panel_recents"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
\ No newline at end of file
+<Space
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="0dp"
+ android:layout_height="0dp" />
\ No newline at end of file
diff --git a/res/values/config.xml b/res/values/config.xml
index 35e5e6d..df0f233 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -133,12 +133,21 @@
<item name="horizontal_spring_damping_ratio" type="dimen" format="float">0.75</item>
<item name="horizontal_spring_stiffness" type="dimen" format="float">200</item>
- <item name="swipe_up_rect_damping_ratio" type="dimen" format="float">0.75</item>
- <item name="swipe_up_rect_stiffness" type="dimen" format="float">200</item>
+ <item name="swipe_up_rect_scale_damping_ratio" type="dimen" format="float">0.75</item>
+ <item name="swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
+
+ <item name="swipe_up_rect_xy_fling_friction" type="dimen" format="float">1.5</item>
+ <item name="swipe_up_rect_xy_damping_ratio" type="dimen" format="float">0.8</item>
+ <item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
<item name="staggered_damping_ratio" type="dimen" format="float">0.7</item>
<item name="staggered_stiffness" type="dimen" format="float">150</item>
+ <!-- Swipe up to home related -->
+ <dimen name="swipe_up_fling_min_visible_change">18dp</dimen>
+ <dimen name="swipe_up_y_overshoot">10dp</dimen>
+ <dimen name="swipe_up_max_workspace_trans_y">-60dp</dimen>
+
<array name="dynamic_resources">
<item>@dimen/all_apps_spring_damping_ratio</item>
<item>@dimen/all_apps_spring_stiffness</item>
@@ -152,10 +161,17 @@
<item>@dimen/horizontal_spring_damping_ratio</item>
<item>@dimen/horizontal_spring_stiffness</item>
- <item>@dimen/swipe_up_rect_damping_ratio</item>
- <item>@dimen/swipe_up_rect_stiffness</item>
+ <item>@dimen/swipe_up_rect_scale_damping_ratio</item>
+ <item>@dimen/swipe_up_rect_scale_stiffness</item>
+
+ <item>@dimen/swipe_up_rect_xy_fling_friction</item>
+ <item>@dimen/swipe_up_rect_xy_damping_ratio</item>
+ <item>@dimen/swipe_up_rect_xy_stiffness</item>
<item>@dimen/staggered_damping_ratio</item>
<item>@dimen/staggered_stiffness</item>
+
+ <item>@dimen/swipe_up_fling_min_visible_change</item>
+ <item>@dimen/swipe_up_y_overshoot</item>
</array>
</resources>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d6e8710..20ebc7a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -80,7 +80,6 @@
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 @@
// UI and state for the overview panel
private View mOverviewPanel;
- private FrameLayout mOverviewPanelContainer;
+ private View mActionsView;
@Thunk
boolean mWorkspaceLoading = true;
@@ -834,6 +833,7 @@
ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
}
}
+
mDragLayer.clearAnimatedView();
}
@@ -924,6 +924,9 @@
@Override
protected void onStop() {
+ final boolean wasActive = isUserActive();
+ final LauncherState origState = getStateManager().getState();
+ final int origDragLayerChildCount = mDragLayer.getChildCount();
super.onStop();
if (mDeferOverlayCallbacks) {
@@ -941,6 +944,20 @@
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
+
+ if (wasActive) {
+ // The expected condition is that this activity is stopped because the device goes to
+ // sleep and the UI may have noticeable changes.
+ mDragLayer.post(() -> {
+ if ((!getStateManager().isInStableState(origState)
+ // The drag layer may be animating (e.g. dismissing QSB).
+ || mDragLayer.getAlpha() < 1
+ // Maybe an ArrowPopup is closed.
+ || mDragLayer.getChildCount() != origDragLayerChildCount)) {
+ onUiChangedWhileSleeping();
+ }
+ });
+ }
}
@Override
@@ -1145,8 +1162,8 @@
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
@@ -1336,11 +1353,16 @@
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
if (mPendingRequestArgs == null) {
+ if (!isInState(NORMAL)) {
+ onUiChangedWhileSleeping();
+ }
mStateManager.goToState(NORMAL);
}
}
};
+ protected void onUiChangedWhileSleeping() { }
+
private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
mWorkspace.updateNotificationDots(updatedDots);
mAppsView.getAppsStore().updateNotificationDots(updatedDots);
@@ -1389,8 +1411,8 @@
return (T) mOverviewPanel;
}
- public FrameLayout getOverviewPanelContainer() {
- return mOverviewPanelContainer;
+ public View getActionsView() {
+ return mActionsView;
}
public DropTargetBar getDropTargetBar() {
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 195e69b..9f25729 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -164,6 +164,15 @@
}
/**
+ * @return {@code true} if the state matches the current state and there is no active
+ * transition to different state.
+ */
+ public boolean isInStableState(LauncherState state) {
+ return mState == state && mCurrentStableState == state
+ && (mConfig.mTargetState == null || mConfig.mTargetState == state);
+ }
+
+ /**
* @see #goToState(LauncherState, boolean, Runnable)
*/
public void goToState(LauncherState state) {
diff --git a/src/com/android/launcher3/anim/FlingSpringAnim.java b/src/com/android/launcher3/anim/FlingSpringAnim.java
index eaf3b1c..06d0f1c 100644
--- a/src/com/android/launcher3/anim/FlingSpringAnim.java
+++ b/src/com/android/launcher3/anim/FlingSpringAnim.java
@@ -15,32 +15,40 @@
*/
package com.android.launcher3.anim;
+import android.content.Context;
+
import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
import androidx.dynamicanimation.animation.FlingAnimation;
import androidx.dynamicanimation.animation.FloatPropertyCompat;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
+import com.android.launcher3.R;
+import com.android.launcher3.util.DynamicResource;
+import com.android.systemui.plugins.ResourceProvider;
+
/**
* Given a property to animate and a target value and starting velocity, first apply friction to
* the fling until we pass the target, then apply a spring force to pull towards the target.
*/
public class FlingSpringAnim {
- private static final float FLING_FRICTION = 1.5f;
- private static final float SPRING_STIFFNESS = 200;
- private static final float SPRING_DAMPING = 0.8f;
-
private final FlingAnimation mFlingAnim;
private SpringAnimation mSpringAnim;
private float mTargetPosition;
- public <K> FlingSpringAnim(K object, FloatPropertyCompat<K> property, float startPosition,
- float targetPosition, float startVelocity, float minVisChange, float minValue,
- float maxValue, float springVelocityFactor, OnAnimationEndListener onEndListener) {
+ public <K> FlingSpringAnim(K object, Context context, FloatPropertyCompat<K> property,
+ float startPosition, float targetPosition, float startVelocity, float minVisChange,
+ float minValue, float maxValue, float springVelocityFactor,
+ OnAnimationEndListener onEndListener) {
+ ResourceProvider rp = DynamicResource.provider(context);
+ float damping = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
+ float stiffness = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
+ float friction = rp.getFloat(R.dimen.swipe_up_rect_xy_fling_friction);
+
mFlingAnim = new FlingAnimation(object, property)
- .setFriction(FLING_FRICTION)
+ .setFriction(friction)
// Have the spring pull towards the target if we've slowed down too much before
// reaching it.
.setMinimumVisibleChange(minVisChange)
@@ -54,8 +62,8 @@
.setStartValue(value)
.setStartVelocity(velocity * springVelocityFactor)
.setSpring(new SpringForce(mTargetPosition)
- .setStiffness(SPRING_STIFFNESS)
- .setDampingRatio(SPRING_DAMPING));
+ .setStiffness(stiffness)
+ .setDampingRatio(damping));
mSpringAnim.addEndListener(onEndListener);
mSpringAnim.animateToFinalPosition(mTargetPosition);
}));
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 531426a..aab6671 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -101,7 +101,7 @@
"Adds localized title and keyword search and ranking");
public static final BooleanFlag ENABLE_PREDICTION_DISMISS = new DeviceFlag(
- "ENABLE_PREDICTION_DISMISS", false, "Allow option to dimiss apps from predicted list");
+ "ENABLE_PREDICTION_DISMISS", true, "Allow option to dimiss apps from predicted list");
public static final BooleanFlag ENABLE_QUICK_CAPTURE_GESTURE = getDebugFlag(
"ENABLE_QUICK_CAPTURE_GESTURE", true, "Swipe from right to left to quick capture");
@@ -143,6 +143,11 @@
"ENABLE_LSQ_VELOCITY_PROVIDER", false,
"Use Least Square algorithm for motion pause detection.");
+ public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS =
+ getDebugFlag(
+ "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false,
+ "Always use hardware optimization for folder animations.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index e33d89f..69f93de 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
+import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_EMPTY;
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
@@ -546,6 +547,8 @@
}
private boolean shouldUseHardwareLayerForAnimation(CellLayout currentCellLayout) {
+ if (ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS.get()) return true;
+
int folderCount = 0;
final ShortcutAndWidgetContainer container = currentCellLayout.getShortcutsAndWidgets();
for (int i = container.getChildCount() - 1; i >= 0; --i) {
diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java
index a3fdf8d..bfeb1dc 100644
--- a/src/com/android/launcher3/logging/FileLog.java
+++ b/src/com/android/launcher3/logging/FileLog.java
@@ -38,7 +38,7 @@
private static final DateFormat DATE_FORMAT =
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
- private static final long MAX_LOG_FILE_SIZE = 4 << 20; // 4 mb
+ private static final long MAX_LOG_FILE_SIZE = 8 << 20; // 4 mb
private static Handler sHandler = null;
private static File sLogsDirectory = null;
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index e93df96..c6192bc 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -35,9 +35,11 @@
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
+import android.os.Debug;
import android.os.Process;
import android.os.RemoteException;
import android.os.StrictMode;
+import android.util.Log;
import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.By;
@@ -117,6 +119,14 @@
// so let's just mark the fact that the leak has happened.
if (sDetectedActivityLeak == null) {
sDetectedActivityLeak = violation.toString();
+ try {
+ Debug.dumpHprofData(
+ getInstrumentation().getTargetContext()
+ .getFilesDir().getPath()
+ + "/ActivityLeakHeapDump.hprof");
+ } catch (IOException e) {
+ Log.e(TAG, "dumpHprofData failed", e);
+ }
}
});
StrictMode.setVmPolicy(builder.build());
@@ -126,18 +136,6 @@
public static void checkDetectedLeaks() {
if (sDetectedActivityLeak != null && !sActivityLeakReported) {
sActivityLeakReported = true;
-
- final UiDevice device = UiDevice.getInstance(getInstrumentation());
- try {
- device.executeShellCommand(
- "am dumpheap "
- + device.getLauncherPackageName()
- + " "
- + getInstrumentation().getTargetContext().getFilesDir().getPath()
- + "/ActivityLeakHeapDump.hprof");
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 17858a0..9b12a62 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -145,7 +145,7 @@
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;