diff options
4 files changed, 53 insertions, 430 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 870e0af5820a..fabc7b771e19 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -86,6 +86,7 @@ public class SwipeHelper implements Gefingerpoken { final private int[] mTmpPos = new int[2]; private int mFalsingThreshold; private boolean mTouchAboveFalsingThreshold; + private boolean mDisableHwLayers; public SwipeHelper(int swipeDirection, Callback callback, Context context) { mCallback = callback; @@ -115,6 +116,10 @@ public class SwipeHelper implements Gefingerpoken { mPagingTouchSlop = pagingTouchSlop; } + public void setDisableHardwareLayers(boolean disableHwLayers) { + mDisableHwLayers = disableHwLayers; + } + private float getPos(MotionEvent ev) { return mSwipeDirection == X ? ev.getX() : ev.getY(); } @@ -147,7 +152,7 @@ public class SwipeHelper implements Gefingerpoken { } } - private float getSize(View v) { + protected float getSize(View v) { return mSwipeDirection == X ? v.getMeasuredWidth() : v.getMeasuredHeight(); } @@ -178,10 +183,12 @@ public class SwipeHelper implements Gefingerpoken { if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) { if (FADE_OUT_DURING_SWIPE && dismissable) { float alpha = swipeProgress; - if (alpha != 0f && alpha != 1f) { - animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); - } else { - animView.setLayerType(View.LAYER_TYPE_NONE, null); + if (!mDisableHwLayers) { + if (alpha != 0f && alpha != 1f) { + animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } else { + animView.setLayerType(View.LAYER_TYPE_NONE, null); + } } animView.setAlpha(getSwipeProgressForOffset(animView)); } @@ -345,7 +352,9 @@ public class SwipeHelper implements Gefingerpoken { duration = fixedDuration; } - animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + if (!mDisableHwLayers) { + animView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } ObjectAnimator anim = createTranslationAnimation(animView, newPos); if (useAccelerateInterpolator) { anim.setInterpolator(mFastOutLinearInInterpolator); @@ -362,7 +371,9 @@ public class SwipeHelper implements Gefingerpoken { if (endAction != null) { endAction.run(); } - animView.setLayerType(View.LAYER_TYPE_NONE, null); + if (!mDisableHwLayers) { + animView.setLayerType(View.LAYER_TYPE_NONE, null); + } } }); anim.addUpdateListener(new AnimatorUpdateListener() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java deleted file mode 100644 index b7c1de36279f..000000000000 --- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright (C) 2014 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.systemui.recents.views; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.util.DisplayMetrics; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; - -/** - * This class facilitates swipe to dismiss. It defines an interface to be implemented by the - * by the class hosting the views that need to swiped, and, using this interface, handles touch - * events and translates / fades / animates the view as it is dismissed. - */ -public class SwipeHelper { - static final String TAG = "SwipeHelper"; - private static final boolean SLOW_ANIMATIONS = false; // DEBUG; - private static final boolean CONSTRAIN_SWIPE = true; - private static final boolean FADE_OUT_DURING_SWIPE = true; - private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true; - - public static final int X = 0; - public static final int Y = 1; - - private static LinearInterpolator sLinearInterpolator = new LinearInterpolator(); - private Interpolator mLinearOutSlowInInterpolator; - - private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec - private int DEFAULT_ESCAPE_ANIMATION_DURATION = 75; // ms - private int MAX_ESCAPE_ANIMATION_DURATION = 150; // ms - private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250; // ms - - public static float ALPHA_FADE_START = 0.15f; // fraction of thumbnail width - // where fade starts - static final float ALPHA_FADE_END = 0.65f; // fraction of thumbnail width - // beyond which alpha->0 - private float mMinAlpha = 0f; - - private float mPagingTouchSlop; - Callback mCallback; - private int mSwipeDirection; - private VelocityTracker mVelocityTracker; - - private float mInitialTouchPos; - private boolean mDragging; - private float mSnapBackTranslationX; - - private View mCurrView; - private boolean mCanCurrViewBeDimissed; - private float mDensityScale; - - public boolean mAllowSwipeTowardsStart = true; - public boolean mAllowSwipeTowardsEnd = true; - private boolean mRtl; - - public SwipeHelper(Context context, int swipeDirection, Callback callback, float densityScale, - float pagingTouchSlop) { - mCallback = callback; - mSwipeDirection = swipeDirection; - mVelocityTracker = VelocityTracker.obtain(); - mDensityScale = densityScale; - mPagingTouchSlop = pagingTouchSlop; - mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, - com.android.internal.R.interpolator.linear_out_slow_in); - } - - public void setDensityScale(float densityScale) { - mDensityScale = densityScale; - } - - public void setSnapBackTranslationX(float translationX) { - mSnapBackTranslationX = translationX; - } - - public void setPagingTouchSlop(float pagingTouchSlop) { - mPagingTouchSlop = pagingTouchSlop; - } - - public void cancelOngoingDrag() { - if (mDragging) { - if (mCurrView != null) { - mCallback.onDragCancelled(mCurrView); - setTranslation(mCurrView, 0); - mCallback.onSnapBackCompleted(mCurrView); - mCurrView = null; - } - mDragging = false; - } - } - - public void resetTranslation(View v) { - setTranslation(v, 0); - } - - private float getPos(MotionEvent ev) { - return mSwipeDirection == X ? ev.getX() : ev.getY(); - } - - private float getTranslation(View v) { - return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY(); - } - - private float getVelocity(VelocityTracker vt) { - return mSwipeDirection == X ? vt.getXVelocity() : - vt.getYVelocity(); - } - - private ObjectAnimator createTranslationAnimation(View v, float newPos) { - ObjectAnimator anim = ObjectAnimator.ofFloat(v, - mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos); - return anim; - } - - private float getPerpendicularVelocity(VelocityTracker vt) { - return mSwipeDirection == X ? vt.getYVelocity() : - vt.getXVelocity(); - } - - private void setTranslation(View v, float translate) { - if (mSwipeDirection == X) { - v.setTranslationX(translate); - } else { - v.setTranslationY(translate); - } - } - - private float getSize(View v) { - final DisplayMetrics dm = v.getContext().getResources().getDisplayMetrics(); - return mSwipeDirection == X ? dm.widthPixels : dm.heightPixels; - } - - public void setMinAlpha(float minAlpha) { - mMinAlpha = minAlpha; - } - - float getAlphaForOffset(View view) { - float viewSize = getSize(view); - final float fadeSize = ALPHA_FADE_END * viewSize; - float result = 1.0f; - float pos = getTranslation(view); - if (pos >= viewSize * ALPHA_FADE_START) { - result = 1.0f - (pos - viewSize * ALPHA_FADE_START) / fadeSize; - } else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) { - result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize; - } - result = Math.min(result, 1.0f); - result = Math.max(result, 0f); - return Math.max(mMinAlpha, result); - } - - /** - * Determines whether the given view has RTL layout. - */ - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - public static boolean isLayoutRtl(View view) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection(); - } else { - return false; - } - } - - public boolean onInterceptTouchEvent(MotionEvent ev) { - final int action = ev.getAction(); - - switch (action) { - case MotionEvent.ACTION_DOWN: - mDragging = false; - mCurrView = mCallback.getChildAtPosition(ev); - mVelocityTracker.clear(); - if (mCurrView != null) { - mRtl = isLayoutRtl(mCurrView); - mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView); - mVelocityTracker.addMovement(ev); - mInitialTouchPos = getPos(ev); - } else { - mCanCurrViewBeDimissed = false; - } - break; - case MotionEvent.ACTION_MOVE: - if (mCurrView != null) { - mVelocityTracker.addMovement(ev); - float pos = getPos(ev); - float delta = pos - mInitialTouchPos; - if (Math.abs(delta) > mPagingTouchSlop) { - mCallback.onBeginDrag(mCurrView); - mDragging = true; - mInitialTouchPos = pos - getTranslation(mCurrView); - } - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mDragging = false; - mCurrView = null; - break; - } - return mDragging; - } - - /** - * @param view The view to be dismissed - * @param velocity The desired pixels/second speed at which the view should move - */ - private void dismissChild(final View view, float velocity) { - final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view); - float newPos; - if (velocity < 0 - || (velocity == 0 && getTranslation(view) < 0) - // if we use the Menu to dismiss an item in landscape, animate up - || (velocity == 0 && getTranslation(view) == 0 && mSwipeDirection == Y)) { - newPos = -getSize(view); - } else { - newPos = getSize(view); - } - int duration = MAX_ESCAPE_ANIMATION_DURATION; - if (velocity != 0) { - duration = Math.min(duration, - (int) (Math.abs(newPos - getTranslation(view)) * - 1000f / Math.abs(velocity))); - } else { - duration = DEFAULT_ESCAPE_ANIMATION_DURATION; - } - - ValueAnimator anim = createTranslationAnimation(view, newPos); - anim.setInterpolator(sLinearInterpolator); - anim.setDuration(duration); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mCallback.onChildDismissed(view); - if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) { - view.setAlpha(1.f); - } - } - }); - anim.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) { - view.setAlpha(getAlphaForOffset(view)); - } - } - }); - anim.start(); - } - - private void snapChild(final View view, float velocity) { - final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view); - ValueAnimator anim = createTranslationAnimation(view, mSnapBackTranslationX); - int duration = SNAP_ANIM_LEN; - anim.setDuration(duration); - anim.setInterpolator(mLinearOutSlowInInterpolator); - anim.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) { - view.setAlpha(getAlphaForOffset(view)); - } - mCallback.onSwipeChanged(mCurrView, view.getTranslationX()); - } - }); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) { - view.setAlpha(1.0f); - } - mCallback.onSnapBackCompleted(view); - } - }); - anim.start(); - } - - public boolean onTouchEvent(MotionEvent ev) { - if (!mDragging) { - if (!onInterceptTouchEvent(ev)) { - return mCanCurrViewBeDimissed; - } - } - - mVelocityTracker.addMovement(ev); - final int action = ev.getAction(); - switch (action) { - case MotionEvent.ACTION_OUTSIDE: - case MotionEvent.ACTION_MOVE: - if (mCurrView != null) { - float delta = getPos(ev) - mInitialTouchPos; - setSwipeAmount(delta); - mCallback.onSwipeChanged(mCurrView, delta); - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - if (mCurrView != null) { - endSwipe(mVelocityTracker); - } - break; - } - return true; - } - - private void setSwipeAmount(float amount) { - // don't let items that can't be dismissed be dragged more than - // maxScrollDistance - if (CONSTRAIN_SWIPE - && (!isValidSwipeDirection(amount) || !mCallback.canChildBeDismissed(mCurrView))) { - float size = getSize(mCurrView); - float maxScrollDistance = 0.15f * size; - if (Math.abs(amount) >= size) { - amount = amount > 0 ? maxScrollDistance : -maxScrollDistance; - } else { - amount = maxScrollDistance * (float) Math.sin((amount/size)*(Math.PI/2)); - } - } - setTranslation(mCurrView, amount); - if (FADE_OUT_DURING_SWIPE && mCanCurrViewBeDimissed) { - float alpha = getAlphaForOffset(mCurrView); - mCurrView.setAlpha(alpha); - } - } - - private boolean isValidSwipeDirection(float amount) { - if (mSwipeDirection == X) { - if (mRtl) { - return (amount <= 0) ? mAllowSwipeTowardsEnd : mAllowSwipeTowardsStart; - } else { - return (amount <= 0) ? mAllowSwipeTowardsStart : mAllowSwipeTowardsEnd; - } - } - - // Vertical swipes are always valid. - return true; - } - - private void endSwipe(VelocityTracker velocityTracker) { - velocityTracker.computeCurrentVelocity(1000 /* px/sec */); - float velocity = getVelocity(velocityTracker); - float perpendicularVelocity = getPerpendicularVelocity(velocityTracker); - float escapeVelocity = SWIPE_ESCAPE_VELOCITY * mDensityScale; - float translation = getTranslation(mCurrView); - // Decide whether to dismiss the current view - boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH && - Math.abs(translation) > 0.6 * getSize(mCurrView); - boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) && - (Math.abs(velocity) > Math.abs(perpendicularVelocity)) && - (velocity > 0) == (translation > 0); - - boolean dismissChild = mCallback.canChildBeDismissed(mCurrView) - && isValidSwipeDirection(translation) - && (childSwipedFastEnough || childSwipedFarEnough); - - if (dismissChild) { - // flingadingy - dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f); - } else { - // snappity - mCallback.onDragCancelled(mCurrView); - snapChild(mCurrView, velocity); - } - } - - public interface Callback { - View getChildAtPosition(MotionEvent ev); - - boolean canChildBeDismissed(View v); - - void onBeginDrag(View v); - - void onSwipeChanged(View v, float delta); - - void onChildDismissed(View v); - - void onSnapBackCompleted(View v); - - void onDragCancelled(View v); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 9c5756ba1119..a8aa8fb592ce 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -1115,14 +1115,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } - public boolean isTransformedTouchPointInView(float x, float y, TaskView tv) { - final float[] point = new float[2]; - point[0] = x; - point[1] = y; - transformPointToViewLocal(point, tv); - x = point[0]; - y = point[1]; - return (0 <= x) && (x < tv.getWidth()) && (0 <= y) && (y < tv.getHeight()); + public boolean isTouchPointInView(float x, float y, TaskView tv) { + return (tv.getLeft() <= x && x <= tv.getRight()) && + (tv.getTop() <= y && y <= tv.getBottom()); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java index 31f75597eab7..a0bb0ef9caef 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java @@ -20,6 +20,7 @@ import android.animation.ValueAnimator; import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; +import android.util.DisplayMetrics; import android.util.Log; import android.view.InputDevice; import android.view.MotionEvent; @@ -29,6 +30,7 @@ import android.view.ViewConfiguration; import android.view.ViewParent; import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; +import com.android.systemui.SwipeHelper; import com.android.systemui.recents.Constants; import com.android.systemui.recents.Recents; import com.android.systemui.recents.events.EventBus; @@ -80,19 +82,21 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { Resources res = context.getResources(); ViewConfiguration configuration = ViewConfiguration.get(context); mContext = context; + mSv = sv; + mScroller = scroller; mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mScrollTouchSlop = configuration.getScaledTouchSlop(); mWindowTouchSlop = configuration.getScaledWindowTouchSlop(); - mSv = sv; - mScroller = scroller; mFlingAnimUtils = new FlingAnimationUtils(context, 0.2f); - - float densityScale = res.getDisplayMetrics().density; mOverscrollSize = res.getDimensionPixelSize(R.dimen.recents_stack_overscroll); - mSwipeHelper = new SwipeHelper(context, SwipeHelper.X, this, densityScale, - configuration.getScaledPagingTouchSlop()); - mSwipeHelper.setMinAlpha(1f); + mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) { + @Override + protected float getSize(View v) { + return mSv.getWidth(); + } + }; + mSwipeHelper.setDisableHardwareLayers(true); } /** Velocity tracker helpers */ @@ -117,7 +121,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { for (int i = taskViewCount - 1; i >= 0; i--) { TaskView tv = taskViews.get(i); if (tv.getVisibility() == View.VISIBLE) { - if (mSv.isTransformedTouchPointInView(x, y, tv)) { + if (mSv.isTouchPointInView(x, y, tv)) { return tv; } } @@ -345,7 +349,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { @Override public void onBeginDrag(View v) { TaskView tv = (TaskView) v; - mSwipeHelper.setSnapBackTranslationX(tv.getTranslationX()); + // Disable clipping with the stack while we are swiping tv.setClipViewInStack(false); // Disallow touch events from this task view @@ -358,8 +362,8 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { } @Override - public void onSwipeChanged(View v, float delta) { - // Do nothing + public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) { + return true; } @Override @@ -377,7 +381,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { } @Override - public void onSnapBackCompleted(View v) { + public void onChildSnappedBack(View v) { TaskView tv = (TaskView) v; // Re-enable clipping with the stack tv.setClipViewInStack(true); @@ -389,4 +393,20 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { public void onDragCancelled(View v) { // Do nothing } + + @Override + public View getChildContentView(View v) { + return v; + } + + @Override + public boolean isAntiFalsingNeeded() { + return false; + } + + @Override + public float getFalsingThresholdFactor() { + return 0; + } + } |